I am currently programming an application in tkinter and I want it to be usable on different kind of systems with low-end or old hardware. To make it easier for myself I will only support displays of 720p and up. The program is now kind of rescalable but the notebook element (containing 10 pages) is giving me issues. When the program starts it runs as a 720p spec not resizable window, and it has a fullscreen button.
The notebook code for not fullscreen mode (720p window):
itemsNotebook = ttk.Notebook(middleRight)
itemsNotebook.grid(row=0, column=0, padx = 20, pady = 10, sticky = N)
print(str(screenWidth) "x" str(screenHeight))
pageOne = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageTwo = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageThree = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageFour = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageFive = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageSix = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageSeven = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageEight = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageNine = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
pageTen = Frame(itemsNotebook, width=652, height = 536, bg = "#333333")
I understand what this part does, it makes the notebook a certain size on the window while not in fullscreen mode. My program has a button to enter fullscreen mode with a function connected to it.
The fullscreen toggle code:
def screenModeToggle():
global fullscreen
global blockScreenAdjustment
if screenWidth >= 1280 and screenHeight >= 720:
fullscreen = not fullscreen
mainWindow.attributes("-fullscreen", fullscreen)
else:
tkinter.messagebox.showwarning("screen size too small", "Your screen has to be at least 720p (1280x720) to enter fullscreen mode.")
blockScreenAdjustment = True
print("screen adjustment blocked!")
if fullscreen == True and blockScreenAdjustment == False and screenWidth >= 1920 and screenHeight >= 1080:
pageOne.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageTwo.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageThree.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageFour.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageFive.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageSix.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageSeven.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageEight.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageNine.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
pageTen.config(width=math.floor((1078/1707)*screenWidth), height=math.floor((776/960)*screenHeight))
if fullscreen == False and blockScreenAdjustment == False:
pageOne.config(width=652, height = 536)
pageTwo.config(width=652, height = 536)
pageThree.config(width=652, height = 536)
pageFour.config(width=652, height = 536)
pageFive.config(width=652, height = 536)
pageSix.config(width=652, height = 536)
pageSeven.config(width=652, height = 536)
pageEight.config(width=652, height = 536)
pageNine.config(width=652, height = 536)
pageTen.config(width=652, height = 536)
The numbers I am calculating are the sizes that look good on my current display configuration. I thought that deviding those numbers through my screen resolution and then multiplying them by the display size the program runs on would do it, but that doesn't work properly. The notebook stays too small for higher resolutions and too big for smaller resolutions.
The screenHeight
and screenWidth
are variables containing the height and the width of the screen using this code:
screenWidth = mainWindow.winfo_screenwidth()
screenHeight = mainWindow.winfo_screenheight()
Can somebody help me getting the scaling and resizing of the notebook correct? The way I have done it feels kind of like a workaround and it doesn't even work properly.
This is my first time here so if I forgot some crucial information please let me know.
CodePudding user response:
As a general rule of thumb, you should not give a width and a height to a Frame
widget. Instead, give sizes to the widgets inside the frame where appropriate (eg: for Text
and Canvas
widgets), and then let the frame grow or shrink to fit the contents.
The second rule of thumb is to design your GUI to work in as small as a space as necessary, and then use geometry manager (pack
, place
, grid
) options to allow the widgets to expand to fill their area.
The following example creates seven tabs, each with a different background color for illustrative purposes. The window is initially set to 800x600, but because of how we added the notebook to the window, the tabs all expand to fill the window.
Also notice that as you manually resize the window, the notebook will automatically expand and shrink. This works even when you force the window to be full screen.
And finally, notice that even though we're creating many tabs, because each one is virtually identical we're able to create them in a loop. Instead of having variables like pageOne
, pageTwo
, etc, we have a single dictionary variable named pages
. This greatly helps in reducing duplicate code.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
root.geometry("800x600")
notebook = ttk.Notebook(root)
notebook.pack(fill="both", expand=True)
pages = {}
for color in ("white", "red", "orange", "green", "blue", "violet", "black"):
page = tk.Frame(notebook, background=color)
pages[color] = page
notebook.add(page, text=color.title())
root.mainloop()