Python:将stdout和stderr重定向到文本小部件会导致程序崩溃

2024-04-26 00:23:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我将stdout和stderr重定向到tkinter文本小部件后,我的程序崩溃了,我认为这应该与缓冲问题有关 我该怎么做?在

我制作了一个可测试的版本,它会产生错误,从而产生错误: 1-运行代码,按开始, 键入“帮助”并按Enter键(重复步骤(2)4-5次 或者更像是随机的)

error image

import Tkinter as tk
import ttk
import sys
import re
import threading

Large_Font= ("Verdana", 12)
Norm_Font= ("Verdana", 10)
Small_Font=("Verdana", 8)




cmdList = ["command1",
           "command1",
           "command1",
           "command1",
           "command1",
           "command1",
           "command1",
           "command1",
           "command1",
           "command1",
           "command1",
           "command1"]

def gui_Input(Data) :
   user_input = Data
   user_input = user_input.strip();   
   user_input = re.sub("\s{2,}" , " ", user_input)    
   inp = user_input.split(' ', 1)
   cmd = inp[0]

   if cmd == 'help' :
      if len(inp) == 1 :
         print "\navailable commands:\n"
         for c in sorted(cmdList) :
            print "        " + c
  return

## 
## GUI
##
def threadit(var):
    thread1 = threading.Thread(target = gui_Input, args =[var]) 
    thread1.start()

class shellGUI(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.title(self, "cmd")

        # Main Container of mosh application
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand = True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {} # instances Dict

        for F in (Startpage, Landpage):

            frame = F(container,self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(Landpage)


    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()


class Landpage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.configure(background="white")

        self.button6 = tk.Button(self, text="Start", 
                            command= lambda: controller.show_frame(Startpage)
                            ,font= Large_Font,  height = 1, width = 13)

        self.button6.place(relx=.445, rely=.75)           


class Startpage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        self.configure(background="#cae1ff")

        # NoteBook
        self.nb = ttk.Notebook(self, name='nb',height=252, width=1040,) # create Notebook in "master"
        self.nb.place(relx=.005, rely=.62) # fill "master" but pad sides

        # Command Line Tab
        self.master_cmd = ttk.Frame(self.nb, name='master-cmd') 


        self.rx_textbox = tk.Text(self.master_cmd, height=13, 
                                  width=127,font=Norm_Font)
        self.rx_textbox.place(relx=.0, rely=.0)   

        self.rx_textbox.tag_configure("stderr", foreground="red")
        self.rx_textbox.bind('<ButtonRelease-1>', self.takeFocus)

        sys.stdout = TextRedirector(self.rx_textbox, "stdout")
        sys.stderr = TextRedirector(self.rx_textbox, "stderr")


        self.cmd_entrybox = tk.Entry(self.master_cmd, width=127, font=Norm_Font) 
        self.contents = tk.StringVar()

        self.cmd_entrybox.config(textvariable=self.contents)


        self.cmd_entrybox.bind('<Key-Return>', self.Button_Bind)

        self.cmd_entrybox.place(relx=.0, rely=.835)


        scrollb = tk.Scrollbar(self.master_cmd ,command=self.rx_textbox.yview)
        scrollb.place(relx =.985 , rely=.0, height = 250)
        self.rx_textbox['yscrollcommand'] = scrollb.set

        self.nb.add(self.master_cmd, text="Command Line     ")

    def Button_Bind(self,event):
        var =  self.contents.get()
        self.cmd_entrybox.delete(0, "end")
        threadit(var)

    def takeFocus(self,event):
        self.cmd_entrybox.focus()

class TextRedirector(object):
    def __init__(self, widget, tag="stdout"):
        self.widget = widget
        self.tag = tag

    def write(self, strng):

        self.widget.configure(state="normal")
        self.widget.insert("end",' '+ strng, (self.tag,))
        self.widget.configure(state="disabled")
        self.widget.see(tk.END)


pad=3  

app= shellGUI()

app.geometry("{0}x{1}+0+0".format(
            app.winfo_screenwidth()-pad, app.winfo_screenheight()-pad))

app.resizable(width=False, height=False)
print '\nEnter your commands below.\r\nType "help" for a list of commands, type "exit" to leave'

app.mainloop()

Tags: selfmastercmdinputinitdefwidgetrx