python + windows automation - 有时候会出现故障

时间:2011-03-17 22:41:25

标签: python windows automation ui-automation pywin32

我正在使用Python自动化一些Windows内容,使用PIL来截取屏幕截图等。问题是,有时候,在某些功能中,我会做一个time.sleep(1),我正在接口的GUI应用程序会冻结那一秒。这是奇怪的原因,在其他地方执行time.sleep不会导致冻结。我无法确切地确定导致冻结的原因以及什么不会......除了主线程和主线程之外的线程中都发生了这种情况。

有什么想法吗?我觉得我只需要一个“放松”功能,让Python停止它正在做的任何事情,让目标UI恢复并刷新和处理输入,然后将它带回Python。什么功能会这样做? (windows Sleep函数似乎就像python的time.sleep一样。)

3 个答案:

答案 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()

编辑:嗯似乎没有这么做......