python - 将 Python 记录器的输出重定向到 tkinter 小部件

标签 python tkinter

我花了一些时间重定向标准输出并将输出记录到 tkinter 文本小部件,我决定需要一些帮助。我的代码如下:

#!/usr/bin/env python
from Tkinter import *
import logging
from threading import Thread

class IODirector(object):
    def __init__(self,text_area):
        self.text_area = text_area

class StdoutDirector(IODirector):
    def write(self,str):
        self.text_area.insert(END,str)
    def flush(self):
        pass

class App(Frame):

    def __init__(self, master):
        self.master = master
        Frame.__init__(self,master,relief=SUNKEN,bd=2)
        self.start()

    def start(self):
        self.master.title("Test")
        self.submit = Button(self.master, text='Run', command=self.do_run, fg="red")
        self.submit.grid(row=1, column=2)
        self.text_area = Text(self.master,height=2.5,width=30,bg='light cyan')
        self.text_area.grid(row=1,column=1)

    def do_run(self):
        t = Thread(target=print_stuff)
        sys.stdout = StdoutDirector(self.text_area)
        t.start()

def print_stuff():
    logger = logging.getLogger('print_stuff')
    logger.info('This will not show')
    print 'This will show'
    print_some_other_stuff()

def print_some_other_stuff():
    logger = logging.getLogger('print_some_other_stuff')
    logger.info('This will also not show')
    print 'This will also show'

def main():    
    logger = logging.getLogger('main')
    root = Tk()
    app = App(root)
    root.mainloop() 

if __name__=='__main__':
    main()

我知道可以根据文本小部件定义一个新的日志记录处理程序,但我无法让它工作。函数“print_stuff”实际上只是许多不同函数的包装器,所有函数都有自己的记录器设置。我需要帮助来定义一个新的“全局”日志记录处理程序,以便可以从每个具有自己的记录器的函数中实例化它。非常感谢任何帮助。

最佳答案

只是为了确保我理解正确:

您想将日志消息打印到您的 STDout 和 Tkinter 文本小部件,但日志不会在标准控制台中打印。

如果这确实是您的问题,请按照以下说明进行操作。

首先让我们在 Tkinter 中制作一个非常简单的控制台,它实际上可以是任何文本小部件,但为了完整起见,我将其包括在内:

class LogDisplay(tk.LabelFrame):
"""A simple 'console' to place at the bottom of a Tkinter window """
    def __init__(self, root, **options):
        tk.LabelFrame.__init__(self, root, **options);

        "Console Text space"
        self.console = tk.Text(self, height=10)
        self.console.pack(fill=tk.BOTH)

现在让我们覆盖日志记录处理程序以重定向到参数中的控制台并仍然自动打印到 STDout:

class LoggingToGUI(logging.Handler):
""" Used to redirect logging output to the widget passed in parameters """
    def __init__(self, console):
        logging.Handler.__init__(self)

        self.console = console #Any text widget, you can use the class above or not

    def emit(self, message): # Overwrites the default handler's emit method
        formattedMessage = self.format(message)  #You can change the format here

        # Disabling states so no user can write in it
        self.console.configure(state=tk.NORMAL)
        self.console.insert(tk.END, formattedMessage) #Inserting the logger message in the widget
        self.console.configure(state=tk.DISABLED)
        self.console.see(tk.END)
        print(message) #You can just print to STDout in your overriden emit no need for black magic

希望对您有所帮助。

关于python - 将 Python 记录器的输出重定向到 tkinter 小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14883648/

相关文章:

python - 使用 matplotlib 自动设置条形图的 y 轴范围

python - Pandas 表示基于另一列的某些列(二进制值)

python - 由于 selenium python 超时而无法定位元素

python - 如何更改标签小部件中的文本大小? (tkinter)

python - UserWarning : Matplotlib is currently using agg, 所以无法显示数字

python - 来自 C 的 Python 中的按位运算

python - 凯拉斯 |运行 Inception v3 示例

Python 3 - Tkinter - askopenfilename - 通过 regEx 过滤文件名(不是按扩展名)

python - 当单击表单上的其他位置时,tkinter 列表框失去了选择

python - Tkinter 国际绑定(bind)