LoginSignup
2
7

More than 3 years have passed since last update.

TkinterでLog出力用windowを作ってみました

Last updated at Posted at 2020-07-13

TkinterでWindowsでGUIを作ると、リアルタイムのprintデバッグが難しいため
メインウィンドウのほかにLog Windowを立ち上げた方が便利だと思い、作ってみました。
あくまでもサブウィンドウなのでToplevelでのWindowを立ち上げます。
(TkinterのToplevel windowsの使いかをちゃんと理解できていません)
ただのLog Windowでは面白くないので、Log種類によって表示/非表示ができるようなチェックボックスを入れてみました。
LogWindow.png

追記: 出力したが、出力に追随してスクロールされなかったので view('end')を追加。
pythonの標準出力に対応するため write(str), flush()を追加

sys.stdout = Logwindow として使えます。

IOLogWindow.py
import sys
import serial
import binascii
import time
import tkinter as tk
from tkinter import scrolledtext

TEXT_COLORS = {
    'MESSAGE' : 'black',
    'INPUT' : 'blue',
    'OUTPUT' : 'green',
    'ERROR' : 'red',
    'DEBUG' : 'yellow'    
    }

# Initial value = flag=True or False
class SimpleCheck(tk.Checkbutton):
    def __init__(self, parent, *args, **kw):
        self.flag = kw.pop('flag')
        self.var =  tk.BooleanVar()
        if self.flag:
            self.var.set(True)
        self.txt = kw["text"]
        tk.Checkbutton.__init__(self, parent, *args, **kw, variable=self.var)

    def get(self):
        return self.var.get()

class IOLogFrame(tk.Frame):
    def __init__(self, master):    
        tk.Frame.__init__(self, master)
        master.title("Log Window")

        #view/hide choice
        select_frame = tk.LabelFrame(master, text= "Log text disable",relief = 'groove')

        self.ckboxs = []
        for key in TEXT_COLORS:
            cb = SimpleCheck(select_frame, text=key, command=self.callback, flag=False)
            self.ckboxs.append(cb)
            cb.pack(side='left')
        select_frame.pack(side = 'top', fill = 'x')

        self.txt = scrolledtext.ScrolledText(master)
        self.txt.pack(fill=tk.BOTH, expand=1)
        for key in TEXT_COLORS:
            self.txt.tag_config(key, foreground=TEXT_COLORS[key])

    def callback(self):
        count = 0
        for key in TEXT_COLORS:
            if(self.ckboxs[count].get()):
                self.hide(key)
            else:
                self.view(key)
            count += 1

    def print(self, str, state='MESSAGE'):
        self.txt.insert(tk.END, str+'\n', state)
        self.txt.see(tk.END)

    def hide(self, tag):
        self.txt.tag_config(tag, elide=True)

    def view(self, tag):
        self.txt.tag_config(tag, elide=False)

    def write(self, str, state='MESSAGE'):
        self.txt.insert(tk.END, str+'\n', state)
        self.txt.see(tk.END)

    def flush(self):
        pass

#sample main window
class IOLogWindow(tk.Toplevel):
    def __init__(self, master):
        master.title("Main WIndow")
        tk.Toplevel.__init__(self, master)
        io = IOLogFrame(self)
        io.print("Message")
        io.print("--ERROR--", 'ERROR')
        io.print("--INPUT--", 'INPUT')
        io.print("--OUTPUT--", 'OUTPUT')
        io.print("--DEBUG--", 'DEBUG')    

if __name__ == '__main__':
    win = tk.Tk()
    io=IOLogWindow(win)
    win.mainloop()

2
7
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
7