首页 文章

按钮单击时,tkinter窗口/框架闪烁

提问于
浏览
0

这是一个tkinter程序,带有一个开始/停止按钮,用于进入和退出记录到文本 Logger 小部件的无限循环 . 我不能为我的生活找出原因,但只有当按下开始按钮时,框架才会闪烁/闪烁,但功能运行正常 . 当我从文件菜单中选择开始时,没有闪存...任何想法为什么这可能是?这是我的代码中的错误吗?

import tkinter as tk
import tkinter.scrolledtext as tkst
from tkinter import ttk
import logging


def popupmsg(msg):
    popup = tk.Tk()
    popup.wm_title("!")
    label = ttk.Label(popup, text=msg)
    label.pack(side="top", fill="x", pady=10)
    b1 = ttk.Button(popup, text="Okay", command=popup.destroy)
    b1.pack()
    popup.mainloop()


class TextHandler(logging.Handler):

    def __init__(self, text):
        # run the regular Handler __init__
        logging.Handler.__init__(self)
        # Store a reference to the Text it will log to
        self.text = text

    def emit(self, record):
        msg = self.format(record)

        def append():
            self.text.configure(state='normal')
            self.text.insert(tk.END, msg + '\n')
            self.text.configure(state='disabled')
            # Autoscroll to the bottom
            self.text.yview(tk.END)

        # This is necessary because we can't modify the Text from other threads
        self.text.after(0, append)

    def create(self, num):
        # Create textLogger
        topframe = tk.Frame(root)
        topframe.pack(side=tk.TOP)
        if num == 0:
            st = tkst.ScrolledText(topframe, state='disabled')
            st.configure(font='TkFixedFont')

            st.pack()

            self.text_handler = TextHandler(st)

            # Add the handler to logger
            self.logger = logging.getLogger()
            self.logger.addHandler(self.text_handler)
            print(num)

        else:
            # Add the handler to logger
            self.logger = logging.getLogger()
            print(num)


def stop():
    root.flag = False


def loop():
    th = TextHandler("none")
    th.create(1)

    def start():
        if root.flag:
            th.logger.error("error")
            root.after(1000, start)
        else:
            th.logger.error("Loop stopped")
            root.flag = True
            return
    start()



class HomePage(tk.Frame):

    def __init__(self, parent):

        tk.Frame.__init__(self, parent)

        #logger and main loop
        th = TextHandler("none")
        th.create(0)
        root.flag = True

        bottomframe = tk.Frame(root)
        bottomframe.pack(side=tk.BOTTOM)

        topframe = tk.Frame(root)
        topframe.pack(side=tk.TOP)

        topframe = tk.Frame(root)
        topframe.pack(side=tk.TOP)

        # Create taskbar/menu
        taskbar = tk.Menu(self.master)
        self.master.config(menu=taskbar)

        file = tk.Menu(taskbar)
        file.add_command(label="Run", command=loop)
        file.add_command(label="Stop", command=stop)
        file.add_separator()
        file.add_command(label="Settings", command=lambda: popupmsg("Coming \"soon\"..."))
        file.add_separator()
        file.add_command(label="Quit", command=quit)
        taskbar.add_cascade(label="File", menu=file)

        startButton = tk.Button(bottomframe, text="Start", command=loop)
        startButton.pack()

        stopButton = tk.Button(bottomframe, text="Stop",  command=stop)
        stopButton.pack()

        exitButton = tk.Button(bottomframe, text="Exit",  command=quit)
        exitButton.pack()


if __name__ == "__main__":
    root = tk.Tk()
    app = HomePage(root)
    root.wm_title("Scraper")
    root.mainloop()

1 回答

  • 1

    我不完全确定为什么,但调整我的代码就这样固定了这个屏幕闪烁 .

    我将 stoploop 函数作为方法移动到 TextHandler 类中 . 这允许我删除对 TextHandler 的第二次调用和 loop 函数中的 create 方法 . 我现在也不需要在 create 方法中使用第二个参数(将其用作一种标志),因此删除了 .

    我猜测只要点击开始按钮,闪光灯就是第二次调用 .

    import tkinter as tk
    import tkinter.scrolledtext as tkst
    from tkinter import ttk
    import logging
    
    
    def popupmsg(msg):
        popup = tk.Tk()
        popup.wm_title("!")
        label = ttk.Label(popup, text=msg)
        label.pack(side="top", fill="x", pady=10)
        b1 = ttk.Button(popup, text="Okay", command=popup.destroy)
        b1.pack()
        popup.mainloop()
    
    
    class TextHandler(logging.Handler):
    
        def __init__(self, text):
            # run the regular Handler __init__
            logging.Handler.__init__(self)
            # Store a reference to the Text it will log to
            self.text = text
    
        def emit(self, record):
            msg = self.format(record)
    
            def append():
                self.text.configure(state='normal')
                self.text.insert(tk.END, msg + '\n')
                self.text.configure(state='disabled')
                # Autoscroll to the bottom
                self.text.yview(tk.END)
    
            # This is necessary because we can't modify the Text from other threads
            self.text.after(0, append)
    
        def create(self):
            # Create textLogger
            topframe = tk.Frame(root)
            topframe.pack(side=tk.TOP)
    
            st = tkst.ScrolledText(topframe, state='disabled')
            st.configure(font='TkFixedFont')
    
            st.pack()
    
            self.text_handler = TextHandler(st)
    
            # Add the handler to logger
            self.logger = logging.getLogger()
            self.logger.addHandler(self.text_handler)
    
        def stop(self):
            root.flag = False
    
        def loop(self):
            def start():
                if root.flag:
                    self.logger.error("error")
                    root.after(1000, start)
                else:
                    self.logger.error("Loop stopped")
                    root.flag = True
                    return
            start()
    
    
    class HomePage(tk.Frame):
    
        def __init__(self, parent):
    
            tk.Frame.__init__(self, parent)
    
            #logger and main loop
            th = TextHandler("none")
            th.create()
            root.flag = True
    
            bottomframe = tk.Frame(root)
            bottomframe.pack(side=tk.BOTTOM)
    
            topframe = tk.Frame(root)
            topframe.pack(side=tk.TOP)
    
            topframe = tk.Frame(root)
            topframe.pack(side=tk.TOP)
    
            # Create taskbar/menu
            taskbar = tk.Menu(self.master)
            self.master.config(menu=taskbar)
    
            file = tk.Menu(taskbar)
            file.add_command(label="Run", command=lambda: th.loop())
            file.add_command(label="Stop", command=lambda: th.loop())
            file.add_separator()
            file.add_command(label="Settings", command=lambda: popupmsg("Coming \"soon\"..."))
            file.add_separator()
            file.add_command(label="Quit", command=quit)
            taskbar.add_cascade(label="File", menu=file)
    
            startButton = tk.Button(text="Start", command=lambda: th.loop())
            startButton.pack()
    
            stopButton = tk.Button(text="Stop",  command=lambda: th.stop())
            stopButton.pack()
    
            exitButton = tk.Button(text="Exit",  command=quit)
            exitButton.pack()
    
    
    if __name__ == "__main__":
        root = tk.Tk()
        app = HomePage(root)
        root.wm_title("Scraper")
        root.mainloop()
    

    ¯\ (ツ)

相关问题