如何在不妨碍 pyautogui 的情况下设置全局热键

问题描述 投票:0回答:1

所以本质上我使用“键盘”库在我的 Python 程序中注册了一个全局热键。它监听按键事件“ctrl+shift+x”以重新启动应用程序。我的程序中有一个脚本,它使用 openCV 在游戏中进行对象检测,并且在其中一次交互过程中,它必须使用 pyautogui 按住 Shift 键来执行操作。在此期间,如果我尝试按全局热键,它不会注册,除非我向它发送垃圾邮件。这很可能是因为 pyautogui 按住了shift。我也尝试过不使用 Shift 的不同组合键,但没有任何进展。

所以我的主界面中有这段代码:

class PrimaryInterface(QMainWindow):
    requestRestart = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("-----")
        self.resize(450, 300)
        self.networkManager = QNetworkAccessManager(self)
        self.setupUI()
        self.checkVersionUpdate()

        self.listener_process = multiprocessing.Process(target=self.registerGlobalHotkey())
        self.listener_process.start()
        self.requestRestart.connect(self.restartApplication)

        def registerGlobalHotkey(self):
        keyboard.add_hotkey('ctrl+shift+x', self.requestRestart.emit)

    def restartApplication(self):
        # Ensures all operations are stopped before restart
        self.cleanupBeforeExit()
        QApplication.quit()
        QProcess.startDetached(sys.executable, sys.argv)

    def cleanupBeforeExit(self):
        # Cleanup code
        keyboard.unhook_all_hotkeys()

        self.networkManager.clearAccessCache() 

这是我的脚本的一部分,使用 pyautogui 执行自动化:

   def dropItems(self, gameplay_screen, last_slot_image):
        if last_slot_image is None:
            print("No last slot image provided.")
            return
        
        # Define the entire inventory area
        inventory_x, inventory_y = 545, 203  # Top-left corner of the inventory
        inventory_width, inventory_height = 197, 264   # Size of the inventory area

        inventory_img = gameplay_screen[inventory_y:inventory_y+inventory_height, inventory_x:inventory_x+inventory_width]

        if last_slot_image.ndim == 3:
            last_slot_image = cv2.cvtColor(last_slot_image, cv2.COLOR_BGR2GRAY)
        if inventory_img.ndim == 3:
            inventory_img = cv2.cvtColor(inventory_img, cv2.COLOR_BGR2GRAY)

        # Perform template matching over the entire inventory area
        res = cv2.matchTemplate(inventory_img, last_slot_image, cv2.TM_CCOEFF_NORMED)
        threshold = 0.7 
        loc = np.where(res >= threshold)

        pyautogui.keyDown('shift')
        first_slot_processed = False

        try:
            for pt in zip(*loc[::-1]):  # Switch x and y positions
                game_location = (pt[0] + inventory_x + last_slot_image.shape[1]//2, pt[1] + inventory_y + last_slot_image.shape[0]//2)
                if not first_slot_processed:
                    self.gwm.smooth_move_and_random_click(game_location, radius=8, smooth_time_min=0.9, smooth_time_max=1.8)
                    first_slot_processed = True
                else:
                    self.gwm.smooth_move_and_random_click(game_location, radius=8, smooth_time_min=0.1, smooth_time_max=0.3)
                time.sleep(random.uniform(.02, .05))
        finally:
            pyautogui.keyUp('shift')

此函数是同一脚本中我的主要 while 循环的一部分。当它执行该功能时,我无法顺利地按全局热键退出并重新启动我的应用程序。

python keyboard keyboard-events pyautogui
1个回答
0
投票

我改用 pynput 作为全局热键监听器,它工作得很好。由于某种原因,每当我的 pyautogui 与键盘交互时,键盘库都不会为我做这件事,但 pynput 能够使用热键组合执行我需要的操作。

© www.soinside.com 2019 - 2024. All rights reserved.