Python Tkinter闪烁标准窗口

时间:2013-09-12 16:10:52

标签: python tkinter

我正在使用TKinter构建一个接口,我有一个问题,每当创建一个新窗口时,200x200像素的标准化tkinter窗口,其中没有任何东西闪烁了几分之一秒,并且在我所有的修改之后(小部件等) 。)制作。这在调用mainloop之前和之后发生。

  • 创建主界面。
  • Mainloop stats
  • 闪烁窗口
  • 出现主界面

在调用Mainloop之后,这也会在新创建的窗口中发生。

  • 出现主界面 - >按下一个按钮,创建一个新窗口
  • 闪烁窗口
  • 出现新窗口

可悲的是,我不能给你一个示例代码...如果我尝试做一个最小的例子,这不会发生。也许标准窗口已创建,但它的更改速度很快,不会出现在屏幕上。我甚至不知道在这种情况下要查找什么...搜索“tkinter flashing window”不会产生任何结果。

编辑:我找到了问题的根源。它似乎是由wm_iconbitmapFigureCanvasTkAggtkinter.Toplevel引起的。如果您删除代码中的图标,它可以正常工作,不闪烁。但是如果我和其中一个一起使用它,窗口会在创建时闪烁。尝试使用下面的代码。当然,您必须将图标放在工作目录中。

以下是我正在使用的图标的代码示例和the link,但我想任何图标都可以。

# coding=utf-8
import numpy as np
import matplotlib as mpl
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
import os

class INTERFACE(object):
    def __init__(self):
        self.root = tk.Tk()
        self.root.protocol("WM_DELETE_WINDOW", self.EXIT)
        self.root.wm_iconbitmap( os.path.abspath("icon.ico"))  #<---- !!!!!!
        self.root.geometry("1024x768")
        canvas = FigureCanvasTkAgg(self.testfigure(), master=self.root) #<---- !!!!!!
        canvas.get_tk_widget().grid(sticky=tk.N+tk.W+tk.E+tk.S)
        self.root.rowconfigure(0, weight=1)
        self.root.columnconfigure(0, weight=1)
    def testfigure(self):
        x=np.linspace(0, 2*np.pi,100)
        y=np.sin(x)
        fig = mpl.figure.Figure()
        sub = fig.add_subplot(111)
        sub.plot(x,y)
        return fig

    def EXIT(self):
        Top = tk.Toplevel(master=self.root)
        Top.wm_iconbitmap( os.path.abspath("icon.ico"))  #<---- !!!!!!
        Top.transient(self.root)
        Top.resizable(width=False, height=False)
        Top.title("Exit")

        tk.Message(Top,text="Do you really want to quit?", justify=tk.CENTER, width=300).grid(row=0,columnspan=3)
        tk.Button(Top,text="YES",command=self.root.destroy).grid(row=1,column=0)
        tk.Button(Top,text="No",command=self.root.destroy).grid(row=1,column=1)
        tk.Button(Top,text="Maybe",command=self.root.destroy).grid(row=1,column=2)
    def start(self):
        self.root.mainloop()

if __name__ == '__main__':
    INTERFACE().start()

3 个答案:

答案 0 :(得分:1)

我知道这是一个老问题,但我遇到了类似的情况,并找到了解决方案。

就我而言,我已将问题与使用iconbitmap隔离开来。我在调用iconbitmap之前使用after方法调用root.mainloop()设法解决了这个问题。

示例:

from tkinter import *

    root = Tk()

    w = Label(root, text="Hello, world!")
    w.pack()

    root.geometry('300x300+500+500')
    root.after(50, root.iconbitmap('icon.ico'))
    root.mainloop()

此方法也适用于带有图标的Toplevel()窗口。

使用Python 3.5.0在Win 8.1上测试。

编辑:进一步检查后,我注意到行为也相对于root.geometry的存在而变化。我最初的例子没有它,我只是在经过几次尝试之后才注意到它仍然存在同样的问题。 after方法中的时间延迟似乎没有任何改变。

root.geometry方法下方移动after会因某种原因产生同样的问题。

答案 1 :(得分:0)

最有可能的是,初始化代码中的某个位置正在调用updateupdate_idletasks,这会导致在屏幕上绘制GUI的当前状态。

问题的另一个可能来源是,如果您要创建Tk而不是Toplevel的多个实例。

但是,如果没有看到您的代码,我们所能做的就是猜测。

解决此问题的最佳途径是创建一个具有相同行为的小示例。不是因为我们需要它来帮助你,而是因为你为重建bug而付出的努力可能会告诉你导致这个bug的原因。

答案 2 :(得分:0)

这应该有效,但需要win32gui

import win32gui

def FlashMyWindow(title):
    ID = win32gui.FindWindow(None, title)
    win32gui.FlashWindow(ID,True)