#python #win32gui
#python #win32gui
Вопрос:
Используя Win32GUI и Watsup, я пишу немного кода на Python для автоматизации поиска по базе данных, доступ к которой осуществляется через программу, не имеющую интерфейса для этого. Таким образом, я могу взять строку из списка, а затем ввести ее в поле поиска и нажать «поиск».
Однако, когда поиск возвращает более 1000 результатов, программа выдает диалоговое окно с предупреждением, которое является простым уведомлением о количестве результатов, которое останавливает выполнение кода на Python. Я не могу заставить код продвигаться дальше строки, где он нажимает lookup.
На мой взгляд, это может быть потому, что оно не ожидает появления окна или не знает, как обработать предупреждение — но я тоже не знаю, кроме как вручную принять его. Ниже приведен соответствующий пример кода, хотя он, вероятно, не очень поучительный. После «clickButton(LookupButton)» выполнение останавливается.
LookupButtonlocation = elemstring.find("Lookup", AuthNameFieldlocation) - 15
#Use Regex search to find handles
number_regex = re.compile(';(d );')
AuthNameEdit = int(number_regex.search(elemstring[AuthNameFieldlocation:]).group(1))
LookupButton = int(number_regex.search(elemstring[LookupButtonlocation:]).group(1))
#Input new Author into Edit Field
setEditText(AuthNameEdit, "John Campbell")
#Click lookup button
clickButton(LookupButton)
Ответ №1:
Я не пользователь WATSUP, но я делаю что-то очень похожее с помощью pywinauto — в моем случае я запускаю ряд автоматических тестов, которые открывают различные сторонние программы, которые аналогичным образом выдают неудобные диалоговые окна с предупреждениями. Немного сложно иметь дело с диалоговыми окнами, о которых вы не знаете, однако, если вы знаете, какие диалоги появляются, но не когда они появятся, вы можете запустить поток, чтобы просто разобраться с этими всплывающими окнами. Ниже приведен простой пример из того, что я делаю, и использует pywinauto, но вы могли бы адаптировать подход для WATSUP:
import time
import threading
class ClearPopupThread(threading.Thread):
def __init__(self, window_name, button_name, quit_event):
threading.Thread.__init__(self)
self.quit_event = quit_event
self.window_name = window_name
self.button_name = button_name
def run(self):
from pywinauto import application, findwindows
while True:
try:
handles = findwindows.find_windows(title=self.window_name)
except findwindows.WindowNotFoundError:
pass #Just do nothing if the pop-up dialog was not found
else: #The window was found, so click the button
for hwnd in handles:
app = application.Application()
app.Connect(handle=hwnd)
popup = app[self.window_name]
button = getattr(popup, self.button_name)
button.Click()
if self.quit_event.is_set():
break
time.sleep(1) #should help reduce cpu load a little for this thread
По сути, этот поток представляет собой просто бесконечный цикл, который ищет всплывающее окно по имени, и если он его находит, он нажимает на кнопку, чтобы закрыть окно. Если у вас много всплывающих окон, вы можете открыть по одному потоку для каждого всплывающего окна (ошибка, которая, однако, не слишком эффективна). Поскольку это бесконечный цикл, у меня есть поток, который проверяет, установлено ли событие, чтобы позволить мне остановить поток из моей основной программы. Итак, в основной программе я делаю что-то вроде этого:
#Start the thread
quit_event = threading.Event()
mythread = ClearPopupThread('Window Popup Title', 'Yes button', quit_event)
# ...
# My program does it's thing here
# ...
# When my program is done I need to end the thread
quit_event.set()
Это не обязательно единственный способ решить вашу проблему, но это способ, который сработал для меня. Извините, я не могу вам особо помочь с WATSUP (я всегда считал pywinauto немного проще в использовании), но я заметил на домашней странице WATSUP (http://www.tizmoi.net/watsup/intro.html ), Пример 2 выполняет нечто подобное без использования потоков, т. Е. ищет именованное окно и нажимает определенную кнопку в этом окне.