将tkinter Text小部件用作另一个程序的stdout

问题描述 投票:0回答:1

我正在尝试为另一个只使用命令行界面的程序创建一个图形界面。我试图通过将命令行程序输出到tkinter文本小部件来做到这一点。我发现了几个关于将stdout重定向到Text小部件的问题,但是,我无法将它们中的任何一个应用于我的问题。这是我的代码的简化版本,它提出了同样的问题:

GUI程序:

import threading, subprocess, sys
from tkinter import *


class Out(Text):
    def write(self, text):
        self.insert('end', text)
        self.see('end')

    def fileno(self):return 1


def run():
    sys.stdout = out
    subprocess.run(['test2.py', '10'], stdout=out, shell=True)
    sys.stdout = sys.__stdout__

root = Tk()
out = Out(root)
out.pack()
threading.Thread(target=run).start()
mainloop()

命令行程序(同一目录中的testpt2.py):

import time, sys

i = int(sys.argv[1])
while i < 100:
    print(i)
    i += 1
    time.sleep(0.1)

这段代码的问题在于任何地方都没有输出;所有这一切都是一个tkinter窗口打开一个空文本小部件。我尝试使用file对象代替Text小部件,并将数字10-99保存到它。在调试时,我发现write方法实际上从未被调用,但我必须有一个返回整数的fileno方法。


编辑#1:This解决方案适用于我的示例代码,但在我的实际项目中,我需要传递命令行参数。

编辑#2:我添加了一个命令行参数来演示上述内容。

编辑#3:我之前应该说过,但我确实需要输出实时发生。

python tkinter subprocess stdout
1个回答
1
投票

试试这段代码

import threading
from tkinter import *
from subprocess import Popen, PIPE, run


class Out(Text):
    def write(self, text):
        self.insert('end', text)
        self.see('end')

    def fileno(self):return 1

root = Tk()
out = Out(root)

def run():
    global out
    process = Popen(['python','-u','test2.py','10'], stdin=PIPE, stdout=PIPE, bufsize=1)

    while process.poll() is None:
        out.write(process.stdout.readline())


out.pack()
threading.Thread(target=run).start()
mainloop()
© www.soinside.com 2019 - 2024. All rights reserved.