19

I know how to make a window fullscreen in the "main" display, but even when moving my app's window to a secondary display connected to my PC, when I call:

self.master.attributes('-fullscreen', True)

to fullscreen that window, it does so in the "main" display and not in the secondary one (the app's window disappears from the secondary display and instantly appears in the "main" one, in fullscreen).

How can I make it fullscreen in the secondary display?

Justino Rodrigues
  • 552
  • 3
  • 6
  • 16

5 Answers5

7

This works on Windows 7: If the second screen width and height are the same as the first one, you can use win1 or win2 geometry of the following code depending its relative position(leftof or rightof) to have a fullscreen in a secondary display:

from Tkinter import *

def create_win():
    def close(): win1.destroy();win2.destroy()
    win1 = Toplevel()
    win1.geometry('%dx%d%+d+%d'%(sw,sh,-sw,0))
    Button(win1,text="Exit1",command=close).pack()
    win2 = Toplevel()
    win2.geometry('%dx%d%+d+%d'%(sw,sh,sw,0))
    Button(win2,text="Exit2",command=close).pack()

root=Tk()
sw,sh = root.winfo_screenwidth(),root.winfo_screenheight()
print "screen1:",sw,sh
w,h = 800,600 
a,b = (sw-w)/2,(sh-h)/2 

Button(root,text="Exit",command=lambda r=root:r.destroy()).pack()
Button(root,text="Create win2",command=create_win).pack()

root.geometry('%sx%s+%s+%s'%(w,h,a,b))
root.mainloop()
JeanClaudeDaudin
  • 424
  • 6
  • 15
3

Try:

from Tkinter import *

rot = Tk()


wth,hgh = rot.winfo_screenwidth(),rot.winfo_screenheight()
#take desktop width and hight (pixel)
_w,_h = 800,600 #root width and hight
a,b = (wth-_w)/2,(hgh-_h)/2 #Put root to center of display(Margin_left,Margin_top)



def spann():
    def _exit():
        da.destroy()

    da = Toplevel()
    da.geometry('%dx%d+%d+%d' % (wth, hgh,0, 0))

    Button(da,text="Exit",command=_exit).pack()
    da.overrideredirect(1)
    da.focus_set()#Restricted access main menu




Button(rot,text="Exit",command=lambda rot=rot : rot.destroy()).pack()


but = Button(rot,text="Show SUB",command=spann)
but.pack()


rot.geometry('%sx%s+%s+%s'%(_w,_h,a,b))
rot.mainloop()
""" Geometry pattern 'WxH+a+b'
        W = Width
        H = Height
        a = Margin_left+Margin_Top"""
dsgdfg
  • 1,492
  • 11
  • 18
3

Super simple method working in 2021

This works even if both displays are different resolutions. Use geometry to offset the second display by the width of the first display. The format of the geometry string is <width>x<height>+xoffset+yoffset:

root = tkinter.Tk()

# specify resolutions of both windows
w0, h0 = 3840, 2160
w1, h1 = 1920, 1080

# set up a window for first display, if wanted  
win0 = tkinter.Toplevel()
win0.geometry(f"{w0}x{h0}+0+0")

# set up window for second display with fullscreen 
win1 = tkinter.Toplevel()
win1.geometry(f"{w1}x{h1}+{w0}+0") # <- this is the key, offset to the right by w0
win1.attributes("-fullscreen", True)

As long as you know the width of the first display, this will work fine. The X system TK runs on puts the second monitor to the right of the first one by default.

Salvatore
  • 10,815
  • 4
  • 31
  • 69
  • 3
    Forcing it over to the other window works, but setting the fullscreen attribute makes it full screen on the main monitor again. – Timothy Lukas H. Jan 23 '22 at 17:03
  • Make sure you have offset it by the proper amount. I found that when I was off by even a few pixels, it would put it on the main display, but if the offset is just right it will work. – Salvatore May 12 '22 at 22:27
2

Windows, Python 3.8

In this solution, pressing F11 will make the window fullscreen on the current screen.

Note that self.root.state("zoomed") is Windows specific according to doc.

self.root.overrideredirect(True) is weird in Windows and may have unwanted side effects. For instance I've had issues related to changing screen configuration with this option active.

#!/usr/bin/env python3
import tkinter as tk


class Gui:
    fullScreen = False

    def __init__(self):
        self.root = tk.Tk()
        self.root.bind("<F11>", self.toggleFullScreen)
        self.root.bind("<Alt-Return>", self.toggleFullScreen)
        self.root.bind("<Control-w>", self.quit)
        self.root.mainloop()

    def toggleFullScreen(self, event):
        if self.fullScreen:
            self.deactivateFullscreen()
        else:
            self.activateFullscreen()

    def activateFullscreen(self):
        self.fullScreen = True

        # Store geometry for reset
        self.geometry = self.root.geometry()

        # Hides borders and make truly fullscreen
        self.root.overrideredirect(True)

        # Maximize window (Windows only). Optionally set screen geometry if you have it
        self.root.state("zoomed")

    def deactivateFullscreen(self):
        self.fullScreen = False
        self.root.state("normal")
        self.root.geometry(self.geometry)
        self.root.overrideredirect(False)

    def quit(self, event=None):
        print("quiting...", event)
        self.root.quit()


if __name__ == '__main__':
    Gui()
Love
  • 1,709
  • 2
  • 22
  • 30
  • This does not seem to work. The window gets the decorations removed and get the size of the screen, but it is not centered. The position of the fullscreen window will be the same as the starting smaller window (the left top will stay at the same coordinate). – Florian Krause Aug 23 '21 at 17:33
0

I searched for a long time to achieve fullscreen on the subscreen, and finally found that overrideredirect(1)+ root.geometry to the location of the secondary screen can be achieved.(If this can not be achieved I will go to use PyQt5. :(

And even if the window is moved by root.geometry, the fullscreen of the root.wm_attributes('-fullscreen',True) method is still on the main screen。

from tkinter import *
import ctypes.wintypes
def get_monitors_info():
    """Obtain all monitors information and return information for the second monitor"""
    """Windows only - using user32 eliminates the need to install the pywin32 software package"""
    user32 = ctypes.windll.user32
    def _get_monitors_resolution():
        monitors = []
        monitor_enum_proc = ctypes.WINFUNCTYPE(
            ctypes.c_int, ctypes.c_ulong, ctypes.c_ulong, ctypes.POINTER(ctypes.wintypes.RECT), ctypes.c_double)
        # Callback function,to obtain information for each display
        def callback(hMonitor, hdcMonitor, lprcMonitor, dwData):
            monitors.append((lprcMonitor.contents.left, lprcMonitor.contents.top,
                             lprcMonitor.contents.right - lprcMonitor.contents.left,
                             lprcMonitor.contents.bottom - lprcMonitor.contents.top))
            return 1
        # Enumerate all Monitors
        user32.EnumDisplayMonitors(None, None, monitor_enum_proc(callback), 0)
        return monitors
    # All monitors information
    monitors = _get_monitors_resolution()
    return monitors

import tkinter as tk
from PIL import Image, ImageTk
import tkinter.font as tkFont
class MyApp:
    def __init__(self, master):
        self.master = master
        master.title("My App")
        monitors = get_monitors_info()
        if len(monitors) >= 2:
            x1=monitors[1][0]
            y1=monitors[1][1]
            w1=monitors[1][2]
            h1=monitors[1][3]
            print("%dx%d+%d+%d" % (w1, h1, x1, y1))
            "Can move the window via root.geometry, but it cannot be moved to full screen on the secondary monitor via root.wm_attributes('-fullscreen',True) either"
            "The fullscreen top-level window created with overrideredirect(1) can be fullscreen on the secondary screen after moving the position。"
            root.geometry("%dx%d+%d+%d" % (w1, h1, x1, y1))
            # root.wm_attributes('-fullscreen', True)
            root.overrideredirect(1)
            # root.attributes("-topmost", True)
        else:
            w1=monitors[0][2]
            h1 = monitors[0][3]
            root.geometry("%dx%d+%d+%d" % (w1, h1, 0, 0))
            root.overrideredirect(1)
        master.bind('<Double-Button-1>', self.toggle_fullscreen)
        master.bind("<F11>", self.toggle_fullscreen)
        master.bind('<Escape>', self.close)
    def toggle_fullscreen(self, event=None):
        overrideredirect_value = root.overrideredirect()
        if(overrideredirect_value):
            root.overrideredirect(0)
        else:
            root.overrideredirect(1)
    def close(self, event=None):
        # set the running flag to False to stop updating the image
        self.running = False
        # close the window
        self.master.destroy()
root = tk.Tk()
app = MyApp(root)
root.mainloop()

How do I get monitor resolution in Python?

Create a fullscreen app in the secondary screen using tkinter and python 3.7.2

Chen
  • 13
  • 3