pythontkinter

Tkinter different behaviours for alpha using terminal and script


I'm trying to create an interface that has some transparency. I know that should be straightforward, but I'm facing a confusing bug.

If I run the following code in the terminal:

import tkinter as tk
root = tk.Tk()
root.geometry("400x400")
root.attributes("-alpha", 0.5)
root.mainloop()

It works fine, and the window is created perfectly with the dimensions and transparency I requested. However, if I run a script like this (on the same environment):

import tkinter as tk

if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("400x400")
    root.attributes("-alpha", 0.5)
    root.mainloop()

It doesn't work. The dimensions are applied to the new window, but not the transparency.

I tried wm_attributes and attributes. Both do not work when running python script.py.

Am I crazy? Why is there any difference in behaviour?

The environments are the same; I'm using Python 3.13, and no other dependencies are involved. I'm using Ubuntu 22.04 using x11.


Edit:

Here is proof I'm running on the same environment. enter image description here And just so the terminal is clear folder git status environment laptop battery


Solution

  • So, thanks to the comments, I managed to find an answer. When setting attributes like -alpha, some window managers delay applying them until the window is fully realized and shown. By adding root.update_idletasks() before root.attributes("-alpha", 0.5) my script now behaves like the terminal.

    The updated code is now:

    import tkinter as tk
    
    if __name__ == "__main__":
        root = tk.Tk()
        root.geometry("400x400")
        root.update_idletasks()
        root.attributes("-alpha", 0.5)
        root.mainloop()
    

    Thanks for the help! I am leaving the answer here in case someone faces the same issue in the future.


    Given @TheLizzard comments, I think a better solution would be:

    import tkinter as tk
    
    if __name__ == "__main__":
        root = tk.Tk()
        root.geometry("400x400")
        root.after_idle(root.attributes, "-alpha", 0.5)
        root.mainloop()
    

    So, it waits for the window to be idle.