QT / PySide processEvents调用锁定

时间:2013-02-12 04:26:09

标签: python qt pyside

为什么调用processEvents会在最多9秒内阻止什么操作?

我有一个带有基于PySide的QT接口的应用程序,其中UI代码作为较低级别实际应用程序逻辑的分离层。当用户执行执行可能运行一段时间的较低级别应用程序逻辑的操作时,实际发生的是:

  1. 直接在GUI线程上显示进度对话框。
  2. 直接在GUI线程上,低级逻辑启动工作线程。
  3. 直接在GUI线程上,较低级逻辑循环更新进度对话框(间接/解耦)并通过QtGui.qApp.processEvents()(再次间接/解耦)勾选应用程序事件队列。
  4. 在工作线程上,QT函数被调用(再次间接/解耦)以响应事件,并且这些函数通过插槽/信号在GUI线程上发生,当GUI线程(如上所述)调用processEvents()时运行。
  5. 直接在GUI线程上,在循环退出之前,最后一个processEvents()调用阻塞大约9秒。这毕竟是工作线程上的所有逻辑都已完成,并且没有更多的函数等待通过信号/插槽调用在其上运行。此调用中没有与我的应用程序相关的任何内容。它在那做什么?它为什么会阻塞?我尝试过300毫秒的最大处理时间并查看它是否退出,但这没有任何区别。只要它想要,呼叫就会锁定。
  6. 关闭进度对话框,用户重新获得焦点。
  7. 这些都散布在很多文件中,以解耦的方式实现。我会尝试提供片段来描绘流程。

    解耦的低级逻辑工作循环:

        while not completed_event.wait(0.1) and not work_state.is_cancelled():
            work_completeness, work_description = work_state.get_completeness(), work_state.get_description()
            for client in self.clients:
                if work_completeness != last_completeness or work_description != last_description:
                    client.event_prolonged_action_update(client is acting_client, work_description, step_count * work_completeness)
                # THE LAST CALL TO THE NEXT LINE LOCKS UP FOR NO REASON
                client.event_tick(client is acting_client)
            last_completeness, last_description = work_completeness, work_description
    

    PySide / QT层客户端event_tick函数:

    def event_tick(self, active_client):
        # THIS IS WHERE THE LOCK UP HAPPENS
        QtGui.qApp.processEvents()
    

    PySide / QT层中的信号/插槽使用,以获取GUI线程上发生的工作线程调用:

    def event_pre_line_change(self, active_client, line0, line_count):
        self.pre_line_change_signal.emit((line0, line_count))
    
    def event_post_line_change(self, active_client, line0, line_count):
        self.post_line_change_signal.emit((line0, line_count))
    
    def event_uncertain_reference_modification(self, active_client, data_type_from, data_type_to, address, length):
        self.uncertain_reference_modification_signal.emit((data_type_from, data_type_to, address, length))
    

    我使用信号/插槽将工作线程上的调用委托给GUI线程的原因是PySide / QT需要更新UI的原因。

    如果你想更深入地挖掘复制案例:

    • 根据GitHub项目自述文本下载并运行the code
    • 从mega下载test file“NEURO”(< 200KB大小)(道歉,这是最容易上传的网站)。
    • 在PeaSauce中加载NEURO。
    • 转到偏移量0x1A19E(CTRL-G)
    • 将数据类型更改为代码(菜单:编辑/更改地址数据类型/代码)
    • 观察进度对话框来来去去。
    • 观察~9秒锁定。

0 个答案:

没有答案