我正在使用Python自动化一些Windows内容,使用PIL来截取屏幕截图等。问题是,有时候,在某些功能中,我会做一个time.sleep(1)
,我正在接口的GUI应用程序会冻结那一秒。这是奇怪的原因,在其他地方执行time.sleep
不会导致冻结。我无法确切地确定导致冻结的原因以及什么不会......除了主线程和主线程之外的线程中都发生了这种情况。
有什么想法吗?我觉得我只需要一个“放松”功能,让Python停止它正在做的任何事情,让目标UI恢复并刷新和处理输入,然后将它带回Python。什么功能会这样做? (windows Sleep
函数似乎就像python的time.sleep
一样。)
答案 0 :(得分:1)
我觉得我只需要一个“放松” 函数导致Python停止 无论它在做什么,让它 有针对性的UI恢复和刷新 处理输入,然后将其带回 蟒蛇。什么功能会这样做?
调用sleep()
(它的任何变体)将阻止执行您调用它的线程。如果您希望在该线程中拥有响应式UI,这只是您想要做的最后一件事。简而言之,一旦你入睡,你什么都做不了!
当您具有无响应的用户界面时,表示在处理UI的线程中执行长时间运行的任务,或者UI线程正在阻塞。因此,要遵循逻辑,如果你的1秒钟睡觉(它们确实打瞌睡而不是正确的睡眠!)导致UI挂起,它们必须与UI在同一个线程中发生,或者UI是一个线程等待。
我真的不知道你是如何使用PIL的,以及你如何与你正在抓取图像的应用程序进行交互,但是你似乎不太可能注入其他进程。所以我猜这个过程正在等待你的线程。如果是这样,那么解决问题就没有真正的捷径。你只需要花更少的时间做你正在做的事情。致电sleep()
只会让事情变得更糟。
调用SwitchToThread()
也无济于事。它所做的就是允许另一个线程运行(如果有一个等待并准备好运行),但你想要运行的线程。无论如何它都没有太大的区别,因为系统会知道你的线程想要运行并且会在适当的时候再次安排它。
最重要的是,您在UI进程中运行的代码阻止了该进程。您只需要尽快实现,以尽量减少干扰。
答案 1 :(得分:1)
您可能不希望当前线程休眠,而是让应用程序有机会处理其消息。
由于很难委派给应用程序的主消息泵,传统上大多数长时间运行的任务都会调用their own temporary message pump。
def process_messages():
msg = wintypes.MSG ()
while user32.GetMessageA (byref (msg), None, 0, 0) != 0:
user32.TranslateMessage (byref (msg))
user32.DispatchMessageA (byref (msg))
Microsoft-blessed版本为here。代码将事件传递给启动线程的应用程序的事件循环,并在事件队列变空时返回。
我在Python和第三方库中看了一下这个功能的实现,但没有在这么快速的搜索中找到它。
简而言之,您应该在调用自己的process_messages()
函数时执行上述操作,就像在Visual Basic和其他几种Windows语言中完成一样,并避免调用sleep()
。
P.S。您可以调整消息泵以仅泵送消息,直到您正在等待的任务完成。
答案 2 :(得分:0)
哦SwitchToThread
似乎很有希望。或者在Python术语中,ctypes.windll.kernel32.SwitchToThread()
。