简体   繁体   中英

Get command window output to display in widget with tkinter

Quick Project Summary : Make a python widget using Tkinter that displays data from several json and txt files. Needs to work in Windows. Where I'm At : Everything is going great with the json files. But I'm running into trouble with the txt files. I can parse the information I need out of the necessary files with this code:

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

Problem : It displays all the data in the command shell NOT in a seperate widget.

I would like to simply move all of this information from the command shell to a text box widget (or a tkmessage widget but I feel that the text box would be more appropriate). A very long google search process gave me lots of code that doesn't work - any tips? Thanks!

Note: This is NOT all the code - just the part I need help fixing

Here's what I think you want. You want your application to open files and parse them out. For each parsed line, you would like it to insert the text (or append the text) to a text control. I would create a method for each file type to do the parsing. Then I would loop over each file and call the parser as appropriate. When you are finished parsing, you can call

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

Another way to do this is to redirect stdout to your text control and then print the parsed line. I find this latter approach to be a bit more flexible, especially when I want to call a separate program with subprocess and read its output bit by bit. Here's one way to do it with 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()

One approach is to use a simple tkinter label:

# 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")   

Then, a really simple approach for putting text into that label:

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

Alternatively, you can use a tkinter.Text widget. In that case you can insert text with the insert method:

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

One resource I like is http://effbot.org/tkinterbook/text.htm . Unfortunately it is quite hard to go from that text to working Python code :(

Here is a little example program with an ugly little tkinter GUI that adds text to a textbox:

#!/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.")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM