Qt Designer 实时显示 python 脚本的输出
Qt Designer displaying in real time the output of a python script
我尝试编写的应用程序存在一些问题,因此我将首先对所有交互进行某种 "big picture" 描述:
我有一个用 Qt Designer 编写的简单 UI。这将启动一系列 python 脚本,这些脚本对某些文件进行不同类型的操作。通过打印通知用户所有操作,但这发生在命令行中。
到目前为止,所有作品都是 needed/intended.
重要提示:有时需要用户输入:值或只是 "press any key" 类型的东西。同样,在 cmd 行中按预期工作。
现在我要做的是将 cmd 行中 python 脚本产生的所有信息添加到 Qt Designer UI。
什么有效:
我能够获得 python 执行的输出并将其显示在文本编辑对象
中
什么不起作用:
UI 仅在执行结束时更新,并且在脚本执行过程中没有响应
我希望 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"
....
暂时忽略格式错误,我想
在 Qt Designer UI 中实时逐行显示此日志,就像在 cmd/debug 中 python 中一样,而无需 blocking/locking UI.
找到一种方法将 parameter/input 值传递给正在执行的 process.I 认为我可能也需要定义标准输入,但是如何将它从 QtDesigner 传递到进程是我想不通的事情。
谢谢!
嗯,对于任何环顾四周的人来说,第一个问题已经解决了。
如何:
删除了 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 window 输出一样。
正在研究问题 2 的解决方案
第二个问题已解决。
process.stdin.write(my_input_data + '\n')
process.stdin.flush()
这会将它发送到子进程。
最后虽然从子进程读取和从 UI 更新是在一个线程中完成的。更加优雅和安全。
如果有人想知道具体如何,尽管问,我可以添加更多代码示例。
我尝试编写的应用程序存在一些问题,因此我将首先对所有交互进行某种 "big picture" 描述:
我有一个用 Qt Designer 编写的简单 UI。这将启动一系列 python 脚本,这些脚本对某些文件进行不同类型的操作。通过打印通知用户所有操作,但这发生在命令行中。 到目前为止,所有作品都是 needed/intended.
重要提示:有时需要用户输入:值或只是 "press any key" 类型的东西。同样,在 cmd 行中按预期工作。
现在我要做的是将 cmd 行中 python 脚本产生的所有信息添加到 Qt Designer UI。
什么有效: 我能够获得 python 执行的输出并将其显示在文本编辑对象
中什么不起作用: UI 仅在执行结束时更新,并且在脚本执行过程中没有响应
我希望 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"
....
暂时忽略格式错误,我想
在 Qt Designer UI 中实时逐行显示此日志,就像在 cmd/debug 中 python 中一样,而无需 blocking/locking UI.
找到一种方法将 parameter/input 值传递给正在执行的 process.I 认为我可能也需要定义标准输入,但是如何将它从 QtDesigner 传递到进程是我想不通的事情。
谢谢!
嗯,对于任何环顾四周的人来说,第一个问题已经解决了。 如何:
删除了 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 window 输出一样。
正在研究问题 2 的解决方案
第二个问题已解决。
process.stdin.write(my_input_data + '\n')
process.stdin.flush()
这会将它发送到子进程。
最后虽然从子进程读取和从 UI 更新是在一个线程中完成的。更加优雅和安全。 如果有人想知道具体如何,尽管问,我可以添加更多代码示例。