在tkinter小部件中显示命令窗口输出

1 投票
3 回答
6570 浏览
提问于 2025-04-18 13:01

项目简述: 我想用Python的Tkinter库做一个小工具,这个工具可以显示来自几个json和txt文件的数据。这个工具需要在Windows系统上运行。

目前进展: json文件的处理一切顺利。但我在处理txt文件时遇到了问题。我可以用以下代码从需要的文件中提取出我想要的信息:

from Tkinter import *
import re


results = open("sample_results.txt", "r")

for line in results:
    if re.match("(.*)test(.*)", line):
        print line
    if re.match("(.*)number(.*)", line):
        print line
    if re.match("(.*)status(.*)", line):
        print line
    if re.match("(.*)length(.*)", line):
        print line

问题: 现在所有的数据都显示在命令行窗口里,而不是在一个单独的小工具里。

我希望能把这些信息从命令行窗口转移到一个文本框小工具里(或者tkmessage小工具,但我觉得文本框更合适)。我在谷歌上搜索了很久,找到了很多代码,但都不管用——有没有什么建议?谢谢!

注意: 这不是全部代码,只是我需要帮助修复的部分。

3 个回答

0

这里有一个简单的示例程序,它使用了一个看起来不太好看的 tkinter 界面,可以往文本框里添加文字:

#!/usr/bin/env python

try:
    import tkinter
except ImportError:
    import Tkinter as tkinter
import _tkinter
import platform

class TextBoxDemo(tkinter.Tk):
    def __init__(self, parent):
        tkinter.Tk.__init__(self, parent)
        self.parent = parent
        self.wm_title("TextBoxDemo")
        self.textbox = tkinter.Text(self)
        self.textbox.pack()

        self.txt_var = tkinter.StringVar()
        self.entry = tkinter.Entry(self, textvariable=self.txt_var)
        self.entry.pack(anchor="w")

        self.button = tkinter.Button(self, text="Add", command=self.add)
        self.button.pack(anchor="e")


    def add(self):
        self.textbox.insert(tkinter.END, self.txt_var.get())


if __name__ == '__main__':
    try:
        app = TextBoxDemo(None)
        app.mainloop()
    except _tkinter.TclError as e:
        if platform.system() == 'Windows':
            print(e)
            print("Seems tkinter will not run; try running this program outside a virtualenv.")
0

一种方法是使用一个简单的tkinter标签:

# somewhere in your main class, I suppose:
self.log_txt = tkinter.StringVar()                                                                                                                                                                                                                                    
self.log_label = tkinter.Label(self.inputframe, textvariable=self.log_txt, justify=tkinter.LEFT)                                                                                                                                                                      
self.log_label.pack(anchor="w")   

接下来,有一个非常简单的方法可以把文字放到这个标签里:

def log(self, s):                                                                                                                                                                                                                                                         
    txt = self.log_txt.get() + "\n" + s                                                                                                                                                                                                                                   
    self.log_txt.set(txt)  

另外,你也可以使用tkinter的Text组件。在这种情况下,你可以用插入方法来添加文字:

self.textbox = tkinter.Text(parent)
self.textbox.insert(tkinter.END, "some text to insert")

我喜欢的一个资源是 http://effbot.org/tkinterbook/text.htm。可惜的是,从那段文字到能用的Python代码有点难 :(

3

我觉得你想要的是这样的:你希望你的应用程序能够打开文件并解析里面的内容。对于每一行解析出来的内容,你希望能够把这些文本插入到一个文本框里(或者追加到文本框里)。我会为每种文件类型创建一个解析的方法。然后,我会遍历每个文件,按需调用相应的解析器。当你完成解析后,可以调用

self.textbox.insert(tkinter.END, parsed_text)

还有一种方法是把标准输出(stdout)重定向到你的文本框,然后打印解析出来的每一行。我觉得这种方法更灵活,特别是当我想用子进程调用一个单独的程序,并逐步读取它的输出时。下面是用Tkinter实现的一种方式:

import ScrolledText
import sys
import tkFileDialog
import Tkinter


########################################################################
class RedirectText(object):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, text_ctrl):
        """Constructor"""
        self.output = text_ctrl

    #----------------------------------------------------------------------
    def write(self, string):
        """"""
        self.output.insert(Tkinter.END, string)


########################################################################
class MyApp(object):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        self.root = parent
        self.root.title("Redirect")
        self.frame = Tkinter.Frame(parent)
        self.frame.pack()

        self.text = ScrolledText.ScrolledText(self.frame)
        self.text.pack()

        # redirect stdout
        redir = RedirectText(self.text)
        sys.stdout = redir

        btn = Tkinter.Button(self.frame, text="Open file", command=self.open_file)
        btn.pack()

    #----------------------------------------------------------------------
    def open_file(self):
        """
        Open a file, read it line-by-line and print out each line to
        the text control widget
        """
        options = {}
        options['defaultextension'] = '.txt'
        options['filetypes'] = [('all files', '.*'), ('text files', '.txt')]
        options['initialdir'] = '/home'
        options['parent'] = self.root
        options['title'] = "Open a file"

        with tkFileDialog.askopenfile(mode='r', **options) as f_handle:
            for line in f_handle:
                print line

#----------------------------------------------------------------------
if __name__ == "__main__":
    root = Tkinter.Tk()
    root.geometry("800x600")
    app = MyApp(root)
    root.mainloop()

撰写回答