Вопрос или проблема
Вызов метода getPointerPos
из моего класса WindowManager
:
def main():
from WindowManager import *
MyWind = WindowManager()
MyWind.getPointerPos()
if __name__ == '__main__':
main()
Метод getPointerPos
, определенно плохо написан (метод класса WindowManager
):
def getPointerPos(self):
# сравниваем pyautogui и win32
import win32api, pyautogui, pynput
print_r("","ОТЛАДКА КЛАССА: РЕКОРДЕР ДЕЙСТВИЙ: Нажмите 'q' для выхода")
keepGoing = True
def StopCallBack():
KeepGoing = False
h.stop()
while keepGoing :
x_win, y_win = win32api.GetCursorPos()
x_pynput, y_pynput = pyautogui.position()
print(f"win32: ({x_win}, {y_win})\t pynput:({x_pynput}, {y_pynput}) (нажмите 'q' для выхода)")
sleep(0.5)
with pynput.keyboard.GlobalHotKeys({
'q': StopCallBack,
'<ctrl>+c': quit}) as h: h.join()
Что это делает:
позиция указателя блокируется, пока я не нажму ‘q’. Затем она отображается, пока я снова не нажму ‘q’ и так далее. Цикл while никогда не прерывается.
Что ожидается достичь:
позиция указателя должна постоянно выводиться в консоль, а этот while
цикл должен остановиться, когда я нажму ‘q’.
Мысли
Я подозреваю, что цикл while keepGoing
не останавливается, так как нет команды break
, чтобы прервать цикл while
. Я ожидал, что цикл прервется, взяв значение булевой переменной keepGoing
на лету. Тем не менее, я хочу сохранить этот метод “самостоятельным” и “простым” (не создавать много сложных слушателей только для нажатия символа ‘q’) в классе.
Буду признателен за любую помощь.
Ответ или решение
Ваша проблема заключается в том, что переменная keepGoing
в методе getPointerPos
на самом деле не изменяется в функции StopCallBack
, что приводит к тому, что цикл while
никогда не прерывается. Ниже приведён исправленный код, а также объяснение, как это работает.
Исправленный код
import win32api
import pyautogui
import pynput
from time import sleep
class WindowManager:
def getPointerPos(self):
print("DEBUGGING CLASS: ACTION RECORDER: Press 'q' to exit")
keepGoing = True
def StopCallBack():
nonlocal keepGoing # Используем nonlocal для изменения переменной в замыкании
keepGoing = False
# Инициализируем глобальные горячие клавиши
with pynput.keyboard.GlobalHotKeys({
'q': StopCallBack,
'<ctrl>+c': quit}) as h:
while keepGoing:
x_win, y_win = win32api.GetCursorPos()
x_pynput, y_pynput = pyautogui.position()
print(f"win32: ({x_win}, {y_win})\t pynput:({x_pynput}, {y_pynput}) (press 'q' to exit)")
sleep(0.5)
h.stop() # Останавливаем слушатель после выхода из цикла
def main():
MyWind = WindowManager()
MyWind.getPointerPos()
if __name__ == '__main__':
main()
Объяснение изменений
-
Использование
nonlocal
: Чтобы изменить значение переменнойkeepGoing
в функцииStopCallBack
, мы используем ключевое словоnonlocal
. Это позволяет функции доступа к переменной из внешней области видимости (в данном случае — из методаgetPointerPos
). -
Глобальные горячие клавиши: Перемещение инициализации горячих клавиш вне цикла
while
позволяет избежать повторной инициализации на каждой итерации, что упрощает код и потенциально повышает производительность. -
Стоп Listening: После выхода из цикла
while
, вызываетсяh.stop()
, чтобы корректно остановить слушатель горячих клавиш.
Итог
Теперь, когда вы запустите данный код, он будет следить за положением указателя мыши и печатать его постоянно, пока вы не нажмёте клавишу ‘q’. Как только вы ее нажмёте, программа остановится.
Если у вас есть дополнительные вопросы или проблемы, пожалуйста, дайте знать!