Tkinter打印记录日志
   3

Tkinter程序打包后,如何查看程序运行的日志呢?比如关键地点的 print() 记录。

有大致两种方式,1、将日志写入到文本中。2、将日志输出到界面上。

实现原理

我们先看一下 print() 函数的参数信息。注意这一段 file=sys.stdout 这里将打印内容写到了 sys.stdout 即控制台的标准输出。
只有我们重新实现下 sys.stdout 打印日志的功能也就基本出来了。

print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
flush: whether to forcibly flush the stream.

测试日志写入到文件

我写了一个Log类,实现了write,flush,close等方法。运行以下方法,会发现控制台没有输出信息,而是记录在 stdout.txt 中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
import sys
class Log:
    def __init__(self, fname):
        self.fname = fname

    def write(self, info):
        f = open(self.fname, mode="a", encoding='utf-8')
        i = f.write(info)
        f.close()
        return i

    def flush(self):
        pass

    def close(self):
        pass

sys.stdout = Log(fname="stdout.txt")

print("测试一下日志打印")

测试日志写入Tkinter界面

与上面代码类似,sys.stdout = Log(tk=win.widget_dic[’tk_text_log’]) 将要打印日志的组件,传到Log类就行。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import datetime
from tkinter import *
from typing import Dict
from tkinter.ttk import *
import sys


class Log:
    def __init__(self, tk):
        self.tk: Text = tk

    def write(self, info):
        self.tk.insert(1.0, info)
        return 0

    def flush(self):
        pass

    def close(self):
        pass


class WinGUI(Tk):
    widget_dic: Dict[str, Widget] = {}

    def __init__(self):
        super().__init__()
        self.__win()
        self.widget_dic["tk_text_log"] = self.__tk_text_log(self)
        self.widget_dic["tk_button_lhu6z2w5"] = self.__tk_button_lhu6z2w5(self)
        self.widget_dic["tk_button_lhu6zau4"] = self.__tk_button_lhu6zau4(self)

    def __win(self):
        self.title("测试打印日志信息")
        # 设置窗口大小、居中
        width = 386
        height = 251
        screenwidth = self.winfo_screenwidth()
        screenheight = self.winfo_screenheight()
        geometry = '%dx%d+%d+%d' % (width, height,
                                    (screenwidth - width) / 2, (screenheight - height) / 2)
        self.geometry(geometry)
        self.resizable(width=False, height=False)

        # 自动隐藏滚动条
    def scrollbar_autohide(self, bar, widget):
        self.__scrollbar_hide(bar, widget)
        widget.bind("<Enter>", lambda e: self.__scrollbar_show(bar, widget))
        bar.bind("<Enter>", lambda e: self.__scrollbar_show(bar, widget))
        widget.bind("<Leave>", lambda e: self.__scrollbar_hide(bar, widget))
        bar.bind("<Leave>", lambda e: self.__scrollbar_hide(bar, widget))

    def __scrollbar_show(self, bar, widget):
        bar.lift(widget)

    def __scrollbar_hide(self, bar, widget):
        bar.lower(widget)

    def __tk_text_log(self, parent):
        text = Text(parent)
        text.place(x=10, y=90, width=366, height=149)

        return text

    def __tk_button_lhu6z2w5(self, parent):
        def test_print():
            i = datetime.datetime.now()  # 获取当前时间
            print('今天是{}{}{}{}{}秒'.format(
                i.month, i.day, i.hour, i.minute, i.second))

        btn = Button(parent, text="打印", takefocus=False, command=test_print)
        btn.place(x=30, y=30, width=50, height=30)
        return btn

    def __tk_button_lhu6zau4(self, parent):
        def clean():
            self.widget_dic['tk_text_log'].delete(1.0, END)
        btn = Button(parent, text="清空", takefocus=False, command=clean)
        btn.place(x=290, y=30, width=50, height=30)
        return btn


class Win(WinGUI):
    def __init__(self):
        super().__init__()
        self.__event_bind()

    def __event_bind(self):
        pass


if __name__ == "__main__":
    win = Win()
    sys.stdout = Log(tk=win.widget_dic['tk_text_log'])
    win.mainloop()
站长微信
请备注来意
二维码