throwaway17434
throwaway17434

Reputation: 831

Python Tkinter Flashing Standard Window

I am building an Interface with TKinter and I have the problem, that whenever create a new window the standardized tkinter window of 200x200 pixel with nothing in it flashes up for a fraction of a second and AFTER that all my modifications (widgets ect.) are made. This happens before AND after calling the mainloop.

Also after Mainloop was called this happens with newly created windows.

Sadly I cannot give you a sample code... If I try to do a minimal example, this doesn't happen. Maybe the standard window is created, but it is changed so fast, that it doesn't appear on screen. I don't even know what to look up in this case... searching "tkinter flashing window" yields nothing.

EDIT: I found the source of the problem. It seems to be caused by wm_iconbitmap, FigureCanvasTkAgg and tkinter.Toplevel. If you remove the the icon out of the code, it works fine, no flashing. But if I use it together with one of the other, the window flashes when created. Try it out with the code below. You have to put the icon in the working directory of course.

Here is a code sample and the link to the icon I am using, but I suppose any icon will do.

# 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()

Upvotes: 1

Views: 4659

Answers (4)

codeomen
codeomen

Reputation: 1

No need to write any extra code just do this and this works fine for example

# Create the main window
window = tk.Tk()
window.title("Window")
window.iconbitmap("icon.ico")
window_width = 520
window_height = 500

so if I do something like this above code given then there will be screen flickering or flash screen. To solve this issue just don't declare the iconbitmap while creating the window, you can add it when declaring the main event like this

# Create the main window
window = tk.Tk()
window.title("Window")
window_width = 520
window_height = 500

/* ------some codes-------*/

#create the main event
window.iconbitmap("icon.ico")
window.mainloop()

This may solve your problem.

I hope it helps

Upvotes: 0

Joules
Joules

Reputation: 580

I know this is an old question, but I've experienced a similar situation and have found a solution.

In my case, I've isolated the issue to the use of iconbitmap. I've managed to solve it by calling iconbitmap with the after method just before calling root.mainloop().

Example:

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()

This method has worked on Toplevel() windows with icons as well.

Tested on Win 8.1 with Python 3.5.0.

Edit: Upon further inspection I've noticed that the behavior changes relative to root.geometry's presence as well. My initial example didn't have it and I only noticed after a few tries that it still had the same issue. The time delay in the after method doesn't seem to change anything.

Moving root.geometry below the after method yields the same issue for some reason.

Upvotes: 1

user5925113
user5925113

Reputation: 61

This should work but it requires win32gui

import win32gui

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

Upvotes: 0

Bryan Oakley
Bryan Oakley

Reputation: 386352

Most likely, somewhere in your initialization code you're calling update or update_idletasks, which causes the current state of the GUI to be drawn on the screen.

Another possible source of the problem is if you're creating multiple instances of Tk rather than Toplevel.

Without seeing your code, though, all we can do is guess.

Your best route to solving this problem is to create a small example that has the same behavior. Not because we need it to help you, but because the effort you put into recreating the bug will likely teach you what is causing the bug.

Upvotes: 0

Related Questions