【问题标题】:Qt Designer displaying in real time the output of a python scriptQt Designer 实时显示 python 脚本的输出
【发布时间】:2017-06-15 02:28:24
【问题描述】:

我正在尝试编写的应用程序存在一些问题,因此我将首先给出所有交互的“大图”描述:

我有一个用 Qt Designer 编写的简单 UI。这会启动一系列 python 脚本,这些脚本对某些文件进行不同类型的操作。通过打印通知用户所有操作,但这发生在命令行中。 到目前为止,所有工作都按需要/预期工作。

重要提示:有时需要用户输入:值或只是“按任意键”类型的东西。同样,在 cmd 行中按预期工作。

现在我要做的是将 cmd 行中的 python 脚本提供的所有信息添加到 Qt Designer UI。

什么有效: 我能够获得 python 执行的输出并将其显示在 textEdit 对象中

什么不起作用: UI 仅在执行结束时更新,并且在脚本执行过程中没有响应

我希望用户界面在文本输入时逐行更新,而不是批量更新。

我是怎么做的:

class my_ui(QtWidgets.QMainWindow):
    ...
    def button_pressed
         self.__process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
         while self.__process.poll() is None:
            line = self.__process.stdout.readline() 
            print(line)

    def main(self):
        ...
        self.console_output_to_ui()

    def write(self, text):
       self.ui.textEdit.append(text)

    def console_output_to_ui(self):
       sys.stdout = self

现在我抓取的输出如下所示:

....
b"evaluate_condition(): '4'\r\n"
# time delay 1s
b"evaluate_condition(): '5'\r\n"
# time delay 1s
b"evaluate_condition(): '6'\r\n"
....

暂时忽略错误的格式,我想

  1. 在 Qt Designer UI 中实时逐行显示此日志,就像在 python 中的 cmd/debug 中一样,而不会阻塞/锁定 UI。

  2. 找到一种将参数/输入值传递给执行进程的方法。我想我可能也需要定义标准输入,但是如何将它从 QtDesigner 传递给进程是我无法弄清楚的。

谢谢!

【问题讨论】:

    标签: python multithreading python-3.x subprocess qt-designer


    【解决方案1】:

    好吧,对于任何环顾四周的人来说,第一个问题已经解决了。 如何:

    移除了 sys.stdout highjack 并将其替换为线程写入(也删除了不需要的写入函数,与 console_output_to_ui 及其调用相同):

    self.__process = subprocess.Popen(cmd, stdout=PIPE,  universal_newlines=True, shell=False)
    t = Thread(target=self.thread_read)
    t.start()
    
    
    def thread_read(self):
        while self.__process.poll() is None:
            line = self.__process.stdout.readline()
            temp = line.lstrip()
            temp = temp.replace("\n", "")
            # don't print empty lines
            if len(temp) > 1:
                self.ui.textEdit.append(temp)
    

    这样在 ui textEdit 我有一个看起来像这样的日志:

    evaluate_condition(): '6'
    evaluate_condition(): '7'
    evaluate_condition(): '8'
    evaluate_condition(): '9'
    

    它会像 cmd 窗口输出一样逐行更新。

    现在正在研究第 2 号问题的解决方案

    【讨论】:

      【解决方案2】:

      第二个问题已解决。

      process.stdin.write(my_input_data + '\n')
      process.stdin.flush()
      

      这会将它发送到子进程。

      虽然从子进程读取和从 UI 更新是在一个线程中完成的。更加优雅和安全。 如果有人想知道确切的方法,请问,我可以添加更多代码示例。

      【讨论】:

        猜你喜欢
        • 2021-06-14
        • 2010-12-09
        • 1970-01-01
        • 1970-01-01
        • 2017-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多