简体   繁体   中英

Python tkinter: button disappearing after label update

I've been using Python for quite some time now and I made a few applications with GUI's. When I was writing my new application I came across some behaviour of tkinter that I think is just strange.

Consider the following code:

from tkinter import *

root = Tk()
root.geometry('200x200')

label = Label(root, bg='green', text='0', font=('arial', 40, 'bold'))
label.place(x=0, y=0, width=200, height=200)

def add():
    label['text'] = int(label['text']) + 1
    if label['text'] == 10:
        button.place_forget()

button = Button(root, command=add, text='+1', font=('arial', 20, 'bold'))
button.place(x=50, y=50, width=100, height=100)

root.mainloop()

As you would expect, when you run this code you will get a small window with a green background and a button. After you pressed the button 10 times, it disappears, and a '10' is show in the window.

The problem I encountered occures when I use a different parent widget for the button widget. For example, when I change this line

button = Button(root, command=add, text='+1', font=('arial', 20, 'bold'))

to

button = Button(label, command=add, text='+1', font=('arial', 20, 'bold'))

replacing 'root' with 'label', my gui just glitches out. Every time I press the button it disappeares. Sometimes it reappears after a few seconds but sometimes it only reappears when I try to click on it.

After some more testing I found out the button disappears every time the parent label updates.

I was wondering; Why is this happening? And is there a way to fix the problem without using 'root' as the parent for button (this would make my application a lot more complicated, or would at least force me to rebuild a lot of the gui stuff)

I tried to find information about this problem, but I couldn't find any.

I don't think there's a good reason for why you are seeing this behavior. I don't see it on OSX, but the, on OSX buttons behave a bit differently than other platforms. It should be perfectly fine to use a label as a parent to another window without seeing this flickering.

One possible workaround might be to call lift on the button widget whenever you reconfigure the label. Perhaps the stacking order is changing on you, causing the label to be above the button.

Finally, are you aware you can use place with relative coordinates, and that widgets can be relative to other widgets even if there is no parent/child relationship? You seem concerned that you'll have to change a lot of code if you can't create the two widgets in a parent/child relationship.

For example, you can create your widget and call place like this:

button = Button(root, command=add, text='+1', font=('arial', 20, 'bold'))
button.place(in_=label, relx=0, rely=0, relwidth=1, relheight=100)

You'll need to make sure the stacking order is correct. The easiest way is to simply make sure the button is created sometime after creating the label.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM