Transparent background in a Tkinter window
Asked Answered
R

9

24

Is there a way to create a "Loading Screen" in Python 3.x using Tkinter? I mean like the loading screen for Adobe Photoshop, with transparency and so on. I managed to get rid of the frame border already using:

root.overrideredirect(1)

But if I do this:

root.image = PhotoImage(file=pyloc+'\startup.gif')
label = Label(image=root.image)
label.pack()

the image displays fine, but with the grey window background instead of transparency.

Is there a way of adding transparency to a window, but still displaying the image correctly?

Rosco answered 29/9, 2013 at 16:37 Comment(0)
D
9

There is no cross-platform way to make just the background transparent in tkinter.

Dunfermline answered 30/9, 2013 at 12:45 Comment(3)
Is there a Linux way?Malkin
@MericOzcan I believe that's done in the windows manager for LinuxLinell
@MericOzcan I posted a "Linux Way" answer after giving up on a Tkinter way. I tried Tkinter for 90 minutes.Disturbed
S
47

It is possible, but it's OS-dependent. This will work in Windows:

import Tkinter as tk # Python 2
import tkinter as tk # Python 3
root = tk.Tk()
# The image must be stored to Tk or it will be garbage collected.
root.image = tk.PhotoImage(file='startup.gif')
label = tk.Label(root, image=root.image, bg='white')
root.overrideredirect(True)
root.geometry("+250+250")
root.lift()
root.wm_attributes("-topmost", True)
root.wm_attributes("-disabled", True)
root.wm_attributes("-transparentcolor", "white")
label.pack()
label.mainloop()
Sophisticated answered 28/2, 2014 at 22:14 Comment(2)
How can I undo the transparency of the window?Filum
The root.lift() is useless if you are going to call root.attributes("-topmost", True)Shuster
O
24

Here is a solution for macOS:

import tkinter as tk

root = tk.Tk()
# Hide the root window drag bar and close button
root.overrideredirect(True)
# Make the root window always on top
root.wm_attributes("-topmost", True)
# Turn off the window shadow
root.wm_attributes("-transparent", True)
# Set the root window background color to a transparent color
root.config(bg='systemTransparent')

root.geometry("+300+300")

# Store the PhotoImage to prevent early garbage collection
root.image = tk.PhotoImage(file="photoshop-icon.gif")
# Display the image on a label
label = tk.Label(root, image=root.image)
# Set the label background color to a transparent color
label.config(bg='systemTransparent')
label.pack()

root.mainloop()

Screenshot

(tested on macOS Sierra 10.12.21)

Orient answered 31/5, 2017 at 23:21 Comment(10)
Thank you so much for this. Could you please explain why you need both root.wm_attributes("-transparent", True) and root.config(bg='systemTransparent'). What does it do? It works perfectly but the explanation is a bit vagueResidential
You're welcome :) I tried to clarify a bit the comments in the answer. The first command "allows" the window to be transparent by turning off the window shadow, the second one specifies which (transparent) background color to use (See this link)Orient
For macOS BigSur, you have to replace root.overrideredirect(True) with root.overrideredirect(1) and root.overrideredirect(0) after each other.Helsinki
I've tried this on MacOS Big Sur 11.3. Unfortunately, the combination of label.config(bg='systemTransparent') with any of root.wm_attributes("-transparent", True) and/or root.config(bg='systemTransparent') made my window completely transparent - meaning that even the image is not visible... With only root.wm_attributes("-transparent", True), it flashes shortly on start and then disappears; while with root.config(bg='systemTransparent'), it doesn't show up at all.Wolk
@Orient Your comment "# Store the PhotoImage to prevent early garbage collection", is wrong as the image wouldn't actually go out of scope.Shuster
@SiddharthDushantha root.overrideredirect(True) is identical to root.overrideredirect(1). And .overrideredirect is acualty supposed to take in a boolean. From tcl's websiteShuster
label.config(bg='systemTransparent') on MacOS BigSur 11.7 is making the window completely transparent including the image. If I don't add this line then the image has a grey background.Stalkinghorse
The completely transparent window issue can be fixed by using Python 3.11, and reinstalling tkinter with brew install tcl-tk and brew install python-tk. Tested on macOS Monterey.Pygidium
Completely transparent window persists with python 3.11 on mac OS Ventura, after brew install ... @J3soon, any solution?Gravely
Is there a way to allow click-through on a transparent window in Mac OS (Sonoma, 14.5)? Transparent TopLevel windows on Windows allow you to click on the root window below, but on Mac the transparent window accepts/blocks the click.Yseulte
D
9

There is no cross-platform way to make just the background transparent in tkinter.

Dunfermline answered 30/9, 2013 at 12:45 Comment(3)
Is there a Linux way?Malkin
@MericOzcan I believe that's done in the windows manager for LinuxLinell
@MericOzcan I posted a "Linux Way" answer after giving up on a Tkinter way. I tried Tkinter for 90 minutes.Disturbed
G
7

Just use root.config(bg=''), that's all, for example:

from tkinter import *
root = Tk()
root.configure(bg='')
Govan answered 22/8, 2021 at 8:29 Comment(1)
On linux at least, this seems to work - until you move the window and realise that it contains a snapshot of what it was covering rather than being transparant.Cherice
H
4

A cross-platform solution:

from sys import platform
import tkinter as tk
root = tk.Tk()

if platform == "linux" or platform == "linux2":
    root.overrideredirect(True)
    root.wait_visibility(root)
    root.wm_attributes("-alpha", 0.5)
elif platform == "darwin":
    root.overrideredirect(True)
    # Make the root window always on top
    root.wm_attributes("-topmost", True)
    # Turn off the window shadow
    root.wm_attributes("-transparent", True)
    # Set the root window background color to a transparent color
    root.config(bg='systemTransparent')
    root.geometry("+300+300")
    # Store the PhotoImage to prevent early garbage collection
    root.image = tk.PhotoImage(file="photoshop-icon.gif")
    # Display the image on a label
    label = tk.Label(root, image=root.image)
    # Set the label background color to a transparent color
    label.config(bg='systemTransparent')
    label.pack()
elif platform == "win32":
    root.image = tk.PhotoImage(file='startup.gif')
    label = tk.Label(root, image=root.image, bg='white')
    root.overrideredirect(True)
    root.geometry("+250+250")
    root.lift()
    root.wm_attributes("-topmost", True)
    root.wm_attributes("-disabled", True)
    root.wm_attributes("-transparentcolor", "white")
    label.pack()

root.mainloop()
Holiday answered 19/7, 2021 at 15:55 Comment(8)
Instead of using "white" in root.attributes("-transparentcolor", "white"), it would be better to use another colour that is rarely used. Also the root.lift() is useless if you are going to call root.attributes("-topmost", True). And there is no need for the root.geometry("+250+250").Shuster
The Linux portion does not work for me. Background is still opaque. Linux 5.10 and tkInter 8.6.Yovonnda
@user3435121, which desktop manager do you use?Holiday
@Holiday How can I know?Yovonnda
@user3435121, is it a Unit in Ubuntu? Mate, Cinammon in Linux Mint? Gnome3 in Fedora? Try this: printf 'Desktop: %s\nSession: %s\n' "$XDG_CURRENT_DESKTOP" "$GDMSESSION"Holiday
it doesn't work, you can type this: printf '%s\n' "$DESKTOP_SESSION"Holiday
@Holiday Debian 11 (bullseye), XDG_CURRENT_DESKTOP=KDE, XDG_CURRENT_SESSION=KDE, DESKTOP_SESSION=plasmaYovonnda
I dont have a Kde plasma in my computer, you can install another window manager, or try others commands, maybe this: root.wm_attributes("-transparentcolor", 'gray') or root.attributes("-alpha", 0.5) or root.configure(bg='')Holiday
B
3

It's simple: use root.attributes()

In your case, it'd be something like root.attributes("-alpha", 0.5) where 0.5 is the transparency you want, 0 being fully transparent to 1 being opaque.

Brunhild answered 29/9, 2013 at 17:3 Comment(1)
No, that's not actually what I want... I don't want the whole thing to be transparent, only the background. The image itself should stay opaque.Rosco
D
3

The Linux Way - Install pqiv

The "Linux Way" seems to be installing another package:

$ sudo apt install pqiv

Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following NEW packages will be installed:
  pqiv
0 upgraded, 1 newly installed, 0 to remove and 11 not upgraded.
Need to get 34.6 kB of archives.
After this operation, 136 kB of additional disk space will be used.
Get:1 http://ca.archive.ubuntu.com/ubuntu xenial/universe amd64 pqiv amd64 2.2-1 [34.6 kB]
Fetched 34.6 kB in 0s (96.0 kB/s)
Selecting previously unselected package pqiv.
(Reading database ... 442035 files and directories currently installed.)
Preparing to unpack .../archives/pqiv_2.2-1_amd64.deb ...
Unpacking pqiv (2.2-1) ...
Processing triggers for man-db (2.7.5-1) ...
Processing triggers for mime-support (3.59ubuntu1) ...
Setting up pqiv (2.2-1) ...

But as I've had to install xdotool and other packages for my application what's another one right? Plus it will make the docker folks happy :)

The good news is it is only 136KB and automatically places the splash screen in the center of the active monitor instead of the center of the primary monitor or the center of the X11 screen (which can look funny on three monitor systems of different resolutions).


Calling pqiv

From the command line (which you can easily duplicate inside Python with os.popen() or subprocess.Popen()) you simply type:

pqiv -c -c -i m.png

Here's what it looks like with my png image:

mserve transparent splash screen.gif


Closing pqiv

In the terminal I have to send Control + C when loading is finished. In Python you would have to grep the output from ps and kill the job. Pretty straight forward in Linux I guess but probably foreign to our Windows friends.

Credit to Super User answer.

Disturbed answered 16/6, 2021 at 0:19 Comment(2)
This question specifically asked for a tkinter way and people have posted solution that should work on Linux/Windows/MacOS.Shuster
@Shuster I looked for a Linux/Tkinter solution for hours before investing hours in the Linux/pqiv solution. If you have a tkinter solution for round spash window I'd love to see it.Disturbed
E
1

You can do this:window.attributes("-transparentcolor", "somecolor")

Earthworm answered 19/9, 2017 at 15:57 Comment(0)
S
1

For just doing a single image you can do the following.

label = Label(root)
label.config(image='image.gif')
label.config(bg='systemTransparent')

this appears to allow the gif and the alpha channel to shine, on macOS specifically.

Seleucid answered 7/3, 2020 at 23:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.