所以本质上我使用“键盘”库在我的 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 循环的一部分。当它执行该功能时,我无法顺利地按全局热键退出并重新启动我的应用程序。
我改用 pynput 作为全局热键监听器,它工作得很好。由于某种原因,每当我的 pyautogui 与键盘交互时,键盘库都不会为我做这件事,但 pynput 能够使用热键组合执行我需要的操作。