python-3.x 运行外部脚本并在文本小部件中实时打印输出

xfb7svmp  于 2022-11-19  发布在  Python
关注(0)|答案(2)|浏览(149)

我想运行一个外部脚本(demo_print.py),并在文本小部件中实时打印输出。
出现错误:
我的错误是什么?如何达到我的目标?如果你有更简单的解决方案,你可以建议。

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/bin/python3/3.7.4/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/usr/bin/python3/3.7.4/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "example_gui.py", line 37, in test
textbox.insert(tk.END, msg + "\n")
File "example_gui.py", line 20, in write
self.widget.insert('end', textbox)
File "/usr/bin/python3/3.7.4/lib/python3.7/tkinter/__init__.py", line 3272, in insert
self.tk.call((self._w, 'insert', index, chars) + args)
_tkinter.TclError: out of stack space (infinite loop?)

我想运行一个外部脚本(demo_print.py),并在文本小部件中实时打印输出。

示例_图形用户界面.py

import tkinter as tk
import subprocess
import threading
import sys
from functools import partial

# ### classes ####

class Redirect:

    def __init__(self, widget, autoscroll=True):
        self.widget = widget
        self.autoscroll = autoscroll

    def write(self, textbox):
        self.widget.insert('end', textbox)
        if self.autoscroll:
            self.widget.see('end')  # autoscroll

    def flush(self):
        pass

def run(textbox=None):
    threading.Thread(target=test, args=[textbox]).start()

def test(textbox=None):
    p = subprocess.Popen("demo_print.py", stdout=subprocess.PIPE, bufsize=1, text=True)
    while p.poll() is None:
        msg = p.stdout.readline().strip()  # read a line from the process output
        if msg:
            textbox.insert(tk.END, msg + "\n")

if __name__ == "__main__":
    fenster = tk.Tk()
    fenster.title("My Program")
    textbox = tk.Text(fenster)
    textbox.grid()
    scrollbar = tk.Scrollbar(fenster, orient=tk.VERTICAL)
    scrollbar.grid()

    textbox.config(yscrollcommand=scrollbar.set)
    scrollbar.config(command=textbox.yview)

    start_button = tk.Button(fenster, text="Start", command=partial(run, textbox))
    start_button.grid()

    old_stdout = sys.stdout
    sys.stdout = Redirect(textbox)

    fenster.mainloop()
    sys.stdout = old_stdout

演示打印.py

import time
for i in range(10):
    print(f"print {i}")
    time.sleep(1)
fkaflof6

fkaflof61#

好的,首先确保demo_print.py与您的www.example.com在同一个空间main.py不是在文件夹或任何地方,然后您可以这样做:

from demo_print import *
print(whatever u named your output variable in demo_print)

看起来你知道怎么做剩下的事。

efzxgjgh

efzxgjgh2#

由于您直接执行"demo_print.py",因此它必须是 executable,并且在文件中具有正确的 shebang(例如,#!/usr/bin/python -u)。
但是,我建议使用Python可执行文件来执行该文件,而且Redirect类对于您的情况也不是必需的。
下面是修改后的代码:

import tkinter as tk
import subprocess
import threading
import sys
from functools import partial

def run(textbox=None):
    threading.Thread(target=test, args=[textbox]).start()

def test(textbox=None):
    # using the Python executable to run demo_print.py
    p = subprocess.Popen([sys.executable, "-u", "demo_print.py"], stdout=subprocess.PIPE, bufsize=1, text=True)
    while p.poll() is None:
        msg = p.stdout.readline().strip()  # read a line from the process output
        if msg:
            textbox.insert(tk.END, msg + "\n")
            textbox.see(tk.END)

if __name__ == "__main__":
    fenster = tk.Tk()
    fenster.title("My Program")
    textbox = tk.Text(fenster)
    textbox.grid(row=0, column=0)
    scrollbar = tk.Scrollbar(fenster, orient=tk.VERTICAL)
    scrollbar.grid(row=0, column=1, sticky="ns")

    textbox.config(yscrollcommand=scrollbar.set)
    scrollbar.config(command=textbox.yview)

    start_button = tk.Button(fenster, text="Start", command=partial(run, textbox))
    start_button.grid()

    fenster.mainloop()

相关问题