1

我正在使用 Tkinter 在 Python 中编写一个 GUI 程序,我需要一种方法来检查是否发生了按键操作而不使用我所有的 cpu。目前我正在使用线程模块来启动一个线程,该线程将检查按键而不冻结界面(Tkinter)。我在线程内的 while 循环中使用 win32api.GetKeyState() 以便它不断检查键的状态,因为即使窗口没有焦点,它也需要能够判断键是否被按下。问题是程序在我启动线程的那一刻使用 100% cpu。如果我将 time.sleep() 放入循环中,它会显着减少 CPU 使用率,但实际按键与知道您正在按键的时间之间存在延迟。

from Tkinter import *
import win32api

class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()

        coords = StringVar()

        Label(master=self, textvariable=coords).pack()

        def GetCoords():
            coords.set(str(win32api.GetCursorPos()))

        root.bind_all("<Scroll_Lock>", self.GetCoords)



root = Tk()
app = Application(master=root)
#root.wm_iconbitmap(default='INSERT ICON HERE')
#root.wm_title("TITLE OF PROGRAM")
#app.master.maxsize(640, 480)
app.master.minsize(640, 480)
app.master.resizable(0, 0)
app.mainloop()
app.quit()

该脚本给了我以下结果: AttributeError: Application instance has no attribute 'GetCoords'

4

1 回答 1

7

您想要捕获关键事件,而不是轮询当前的键盘状态。

请参阅TkInter 文档中的事件和绑定,它有一个简单的示例,可以完全满足您的需求(另外,它是跨平台的,而不是仅限 Win32)。

这通常是所有 GUI 编程(和网络服务器,就此而言)的问题,答案总是相同的。无论有无线程,您都不会直接有效地使用非阻塞“检查当前 X 状态”调用。在主线程中,您要求事件循环“在 X 状态更改时调用我的函数”,或者您创建一个后台线程并进行阻塞“永远等待直到 X 发生”调用。

事件循环上的维基百科页面实际上对此有很好的描述。


查看您编辑的版本,您现在遇到了一个全新的问题:

class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()

        coords = StringVar()

        Label(master=self, textvariable=coords).pack()

        def GetCoords():
            coords.set(str(win32api.GetCursorPos()))

        root.bind_all("<Scroll_Lock>", self.GetCoords)

GetCoords是内部定义的局部函数Application.__init__。但是您尝试将其用作Application. self.GetCoords除非GetCoordsself. _ 这正是错误消息的AttributeError: Application instance has no attribute 'GetCoords'含义。

但是你可以通过本地函数GetCoords,只需self.去掉前缀。我不确定这会如你所想(因为我不确定你是否可以关闭StringVar类似的东西),但是……试试看。

或者,您可以通过将其移出并给它一个参数来创建一个方法。 然后你可以访问,并获得一个绑定的方法,你可以完全按照你想要的方式传递它。但是,在这种情况下,它将无法再访问,因为这是. 要解决此问题,请将该局部变量更改为成员变量,方法是使用和(以及其他任何地方)的任何地方而不是.GetCoordsdef __init__selfself.GetCoordscoords__init__self.coords__init__GetCoordscoords

于 2013-01-10T00:34:28.217 回答