wxPython:全局热键循环切换

1 投票
2 回答
1026 浏览
提问于 2025-04-17 03:09

我正在尝试创建一个热键切换功能(F12键),当按下它一次时会启动一个循环,再按一次则关闭这个循环。这个循环的功能是在开启时每0.5秒模拟一次鼠标点击。我在wxpython网站上找到了一个关于热键的示例,能够让循环启动,但我不知道怎么让它关闭。我尝试创建一个单独的按键来关闭它,但没有成功。这个鼠标模块可以模拟一次左键点击。

这是我现在的代码:

import wx, win32con, mouse

from time import sleep

class Frameclass(wx.Frame):

    def __init__(self, parent, title):
            super(Frameclass, self).__init__(parent, title=title, size=(400, 200))
            self.Centre()
            self.Show()
            self.regHotKey()
            self.Bind(wx.EVT_HOTKEY, self.handleHotKey, id=self.hotKeyId)
            self.regHotKey2()
            self.Bind(wx.EVT_HOTKEY, self.handleHotKey2, id=self.hotKeyId2)
    def regHotKey(self):
            """
            This function registers the hotkey Alt+F12 with id=150
            """
            self.hotKeyId = 150
            self.RegisterHotKey(self.hotKeyId,win32con.MOD_ALT, win32con.VK_F12)#the key to watch for
           
            
    def handleHotKey(self, evt):
            loop=True
            print('clicks on')
            while loop==True:
            #simulated left mouse click
                 mouse.click()
                 sleep(0.50)
                 
                 x=self.regHotKey2()
                 print(x)
                 if x==False:
                         print('Did it work?')
                         break
            else:
                 pass

---------------------第二次按键热键--------

    def regHotKey2(self):
            self.hotKeyId2 = 100
            self.RegisterHotKey(self.hotKeyId2,win32con.MOD_ALT, win32con.VK_F11)
                    
    def handleHotKey2(self, evt):
            return False
            loop=False
            print(loop)
                         

if name=='main':

showytitleapp=wx.App()
#gotta have one of these in every wxpython program apparently
Frameclass(None, title='Rapid Clicks')
showytitleapp.MainLoop()
#infinite manloop for catching all the program's stuff

2 个回答

1

我在我的导入部分添加了这些模块:

subprocess, signal, sys

在我的类下面,我添加了这些代码:


def init(self, parent, title):
    self.clicker_loop = False
    self.PID=1

def openClicker(self,event):
    self.PID=subprocess.Popen([sys.executable, "123.py"])
我必须导入sys,并在我的popen中添加sys.executable,否则每次我尝试打开另一个Python程序时都会出错。


    def handleHotKey(self, evt):
        if self.clicker_loop:
            self.clicker_loop = False
            print(self.clicker_loop)
            self.PID.terminate()
        else:
            self.clicker_loop = True
            print(self.clicker_loop)
            self.openClicker(self)

我用self.PID.terminate()来结束调用的循环进程,否则它会打开单独的123.py循环文件。

单独的123.py文件包含以下代码:


import mouse
from time import sleep

while True:
    mouse.click()
    sleep(1)

这段代码的基本功能是,当按下热键时,通过subprocess模块调用一个单独的Python文件,然后当再次按下热键时结束那个进程。感谢大家的帮助。

1

你的 loop 变量是在 handleHotKey 函数内部定义的,也就是说它的作用范围只在这个函数里面。因为 regHotKey2 绑定到了 handleHotKey2,而 handleHotKey2 是一个不同的事件监听器,所以它产生的事件不会影响到 handleHotKey 函数里的循环。此外,handleHotKey2 的第一行是一个返回值,这意味着在执行后面的两行代码之前,这个函数就会结束。

出于好奇,运行 x=self.regHotKey2(); print(x) 会输出什么呢?

试着把你的循环变量定义在类的层级,而不是函数的层级 -

def __init__(self, parent, title):
    ... your original stuff ...
    self.clicker_loop = False

然后在你的处理程序中修改 那个 循环 -

def handleHotKey(self, evt):
    self.clicker_loop = True
    while self.clicker_loop:
        ... do the thing ...

def handleHotKey2(self, evt):
    self.clicker_loop = False

请试试看这个方法,告诉我是否有效。

也许这样可以通过同一个热键切换循环...

def handleHotKey(self, evt):
    if self.clicker_loop:
        self.clicker_loop = False
    else:
        self.clicker_loop = True

撰写回答