Widgets disappear when moving the window rapidly

Viewed 236

I noticed this behavior, where moving the window rapidly made the widgets in it disappear.

enter image description here

import tkinter as tk

hidden=tk.Tk()
hidden.attributes('-alpha',0.0)

root=tk.Toplevel(hidden)

bg_label=tk.Label(root)
bg_label.pack()

label=tk.Label(bg_label,text='Example')
label.pack(padx=100,pady=100)

hidden.mainloop()

DESCRIPTION

Basically I am having a transparent window as the main Tk() instance, so that I can have its visibility in the taskbar, as I am using a custom title bar with overrideredirect(True) on its parent window. I have a background label with some image (image not being a contributing factor) and another label packed in it.

OBSERVATIONS

  • The widgets packed in the background label disappear on rapid motion of the window.
  • The widgets are restored on minimizing and re-opening.
  • This doesn't happen if the attributes('-alpha',) of the Toplevel() is anything less than 1.

ADDITIONAL

disappearing label

Below are the actual codes (they are not needed to reproduce the behavior)

Here is the code for the above example

from gui import *

hidden=tk.Tk()
hidden.attributes('-alpha',0.0)

root=tk.Toplevel(hidden)
screen_height=root.winfo_screenheight()
req_height=screen_height//2
req_width=req_height*16//9
root.geometry(f'{req_width}x{req_height+32}+100+100')

tb=TitleBar(root,hidden,fg='white',bg='black',font=('Arial',10))
tb.pack()

img_path=os.path.join('data','images')
bg_image=Image.open(os.path.join(img_path,'example.png'))
bg_image=ImageTk.PhotoImage(bg_image.resize((req_width,req_height),Image.ANTIALIAS))

bg_label=tk.Label(root,bd=0,image=bg_image)
bg_label.pack(fill='both',expand=True)

teacher_button_image=Image.open(os.path.join(img_path,'teacher_button.png'))
teacher_button_image=ImageTk.PhotoImage(teacher_button_image.resize((100,32),Image.ANTIALIAS))
teacher_label=tk.Label(bg_label,image=teacher_button_image)
teacher_label.pack(pady=(200,0))

hidden.mainloop()

And here is the relevant part of gui.py

import tkinter as tk
from tkinter import ttk
from PIL import Image,ImageTk
import os
import webbrowser

class TitleBar:
    def __init__(self,parent,hidden,icon=None,title='App',width=10,bg=None,fg=None,font=None,iconlink=None):

        def get_pos(event):
            xwin = self.parent.winfo_x()
            ywin = self.parent.winfo_y()
            startx = event.x_root
            starty = event.y_root
            ywin = ywin - starty
            xwin = xwin - startx

            def move_window(event):
                self.parent.geometry('+{0}+{1}'.format(event.x_root+xwin, event.y_root+ywin))

            self.title_frame.bind('<B1-Motion>',move_window)

        def on_iconify(event):
            if self.parent.state()=='normal':
                self.parent.withdraw()
            else:
                on_deiconify(None)

        def on_deiconify(event):
            self.parent.deiconify()

        def dest(evrnt):
            self.parent.destroy()
            self.hidden.destroy()

        def on_enter_close(event):
            self.close_label.config(image=self.close_title_button_hover)

        def on_leave_close(event):
            self.close_label.config(image=self.close_title_button)

        def on_enter_minimise(event):
            self.minimise_label.config(image=self.minimise_title_button_hover)

        def on_leave_minimise(event):
            self.minimise_label.config(image=self.minimise_title_button)

        def icon_link(event):
            if self.iconlink:
                webbrowser.open(self.iconlink)

        self.width=width
        self.parent=parent
        self.hidden=hidden
        self.icon=icon
        self.iconlink=iconlink

        self.close_title_button=ImageTk.PhotoImage(close_title_button.resize((self.width,self.width),Image.ANTIALIAS))
        self.close_title_button_hover=ImageTk.PhotoImage(close_title_button_hover.resize((self.width,self.width),Image.ANTIALIAS))
        self.minimise_title_button_hover=ImageTk.PhotoImage(minimise_title_button_hover.resize((self.width,self.width),Image.ANTIALIAS))
        self.minimise_title_button=ImageTk.PhotoImage(minimise_title_button.resize((self.width,self.width),Image.ANTIALIAS))
        self.title_frame=tk.Frame(self.parent,bg=bg)
        if icon:
            self.logo_icon=ImageTk.PhotoImage(Image.open(self.icon).resize((self.width+10,self.width+10),Image.ANTIALIAS))
            self.logo_label=tk.Label(self.title_frame,image=self.logo_icon,bd=0,bg=bg,cursor='hand2')
            self.logo_label.pack(side='left',padx=(10,5))
            self.logo_label.bind('<Button-1>',icon_link)
        self.title_label=tk.Label(self.title_frame,text=title,bg=bg,fg=fg,font=font)
        self.title_label.pack(side='left')
        self.close_label=tk.Label(self.title_frame,image=self.close_title_button,bd=0,bg=bg)
        self.close_label.pack(side='right',ipadx=10,ipady=11)
        self.close_label.bind('<Button-1>',dest)
        self.close_label.bind('<Enter>',on_enter_close)
        self.close_label.bind('<Leave>',on_leave_close)
        self.minimise_label=tk.Label(self.title_frame,image=self.minimise_title_button,bd=0,bg=bg)
        self.minimise_label.pack(side='right',ipadx=10,ipady=11)
        self.minimise_label.bind('<Button-1>',on_iconify)
        self.minimise_label.bind('<Enter>',on_enter_minimise)
        self.minimise_label.bind('<Leave>',on_leave_minimise)
        self.title_frame.bind('<Button-1>',get_pos)
        self.title_label.bind('<Button-1>',get_pos)
        self.hidden.bind('<Map>',on_deiconify)
        self.hidden.bind('<Unmap>',on_iconify)

    def pack(self):
        self.parent.overrideredirect(True)
        self.parent.geometry('+100+100')
        self.title_frame.pack(side='top',anchor='e',fill='x')
        if self.icon:
            self.parent.iconphoto(False,self.logo_icon)
            self.hidden.iconphoto(False,self.logo_icon)

I would love to know the reason for the same and how to prevent this, any help is greatly appreciated.

1 Answers

The problem is in below line.

bg_label=tk.Label(root)

You should replace it with the following:

bg_label=tk.Frame(root)
Related