Search code examples
python-3.xtkinterwindows-10python-imaging-librarytkinter-canvas

Automatically Re-Forcing Tkinter Canvas Fullscreen Image on Top (Windows 10, Python)


The goal is to show the image with no border, full screen, and keep its focus no matter what happens on the computer. The program shows an image in our lobby that clients occasionally see, so it is important to keep the focus on the image even when something weird happens. So far, computer update messages and random file system errors have popped up and have sat on top of it. Unfortunately, there isn't anybody who can check on it to bring focus back manually. This would be a bad solution, anyways.

So, the problem is that the program is stuck running on the popup.mainloop() line when the image is displayed, so I'm not sure how to run any other code to check for and deal with other windows appearing on top after the image is displayed.

Here's what I have so far, it just opens the image full screen. I tried adding popup.lift() in a loop before and after popup.mainloop() and neither worked. I also saw this post but couldn't manage to build something that refocuses the window.

import pyautogui as pa
import datetime
import tkinter
from PIL import Image, ImageTk

def showPIL(pilImage):
    popup = tkinter.Tk()
    w, h = popup.winfo_screenwidth(), popup.winfo_screenheight()
    popup.attributes('-fullscreen',True) 
    popup.geometry("%dx%d+0+0" % (w, h))
    popup.focus_set()

    # Want to be able to exit on command
    popup.bind("<Escape>", lambda e: (e.widget.withdraw(), e.widget.exit()))
    canvas = tkinter.Canvas(popup, width=w, height=h, highlightthickness=0)
    canvas.pack()
    canvas.configure(background='black')

    imgWidth, imgHeight = pilImage.size
    if imgWidth != w or imgHeight != h:
        ratio = min(w/imgWidth, h/imgHeight)
        imgWidth = int(imgWidth*ratio)
        imgHeight = int(imgHeight*ratio)
        pilImage = pilImage.resize((imgWidth, imgHeight))

    image = ImageTk.PhotoImage(pilImage)
    canvas.create_image(w/2, h/2, image=image)
    popup.mainloop()


if __name__ == '__main__':
    # program won't terminate if mouse goes into the corner.
    pa.FAILSAFE = False

    pilImage = Image.open(r"C:\directory\to\your\image.png")

    pa.moveTo(pa.size().width, 1000)  # Move mouse to side of screen
    
    # five_pm = datetime.time(hour=17, minute=0)
    # while datetime.datetime.now().time() < five_pm:
    showPIL(pilImage)

Solution

  • This can be fixed by setting popup.attributes('-topmost', True) to keep your window on top of everything else.