Python Tkinter application fit on screen - python

I have designed an application using the Tkinter module from Python, on my 17"
screen.
Is there a way to make this app fit on lower resolution screens? I have tried to run it on a 14" screen, and the app doesn`t fit well.
Thank you.

You can get the screen resolution then input them in your root.geometry, this way:
from Tkinker import *
root = Tk()
width, height = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry('%dx%d+0+0' % (width,height))
root.mainloop()

You need to use this one line:
root.state('zoomed') #works on all operating systems
root = tkinter.Tk()
root.state('zoomed')
This will fit the window perfectly to the display. (Note: This is not full screen function. Full screen means the window will also cover the taskbar, but in this code window fits all over the screen except the taskbar)

Related

Unable To Repeatedly Get TKinter Window Dimensions

Recently I tried creating the function in which all items on a TKinter GUI will resize themselves to fit the screen, but I cannot seem to figure out how to do this. I did try this:
from tkinter import *
root = Tk()
root.geometry("710x300")
def dimloop():
root.update()
screenwidth = root.winfo_screenwidth()
print(root.winfo_screenwidth())
button.config(width=round(screenwidth/7.1))
root.after(10, dimloop)
button = Button(root, text = 'Hello', width=100)
button.place(x=0, y=0)
dimloop()
root.mainloop()
But That Did Not Work. Does Anyone Know Any Way To Do This?
The screenwidth function returns the width of the physical screen. That's not going to change.
If you want the width of the root window you should use root.winfo_width(). There's no point in doing this in a loop, you can get the width of the screen and then set the window width and height using the geometry method to force it to be a particular size.

How do I create a new python tkinter window so fits exactly in the available desktop area, but isn't maximized?

(Environment: Windows, Python 3)
My problem is that using .geometry to set a height & width sets the height & width of the space inside the window - the title bar and window border make it larger. Below is my code so far. As you'll see, even though I have it create a window that's the exact size of the available screen area, the window ends up being too big because the title bar and borders aren't accounted for when setting the size.
See that "what needs to change here" part? What do those two statements need to be changed to or replaced with, that's simple? (If you have it right, the window should fit exactly in the available space on your desktop, with title bar and borders clearly visible.)
Please keep it simple - I'm still new to all of this. :-)
#Important variables:
#screenAvailableWidth, screenAvailableHeight: Height & width of
# screen without
# taskbar
#windowWidth, windowHeight: Height & width of new window to create
#window: Object of class Tk() from tkinter.
#Get screen height and width WITHOUT including the taskbar.
#This part works fine - I've tested the result and it's good.
from win32api import GetMonitorInfo, MonitorFromPoint
monitorInfo = GetMonitorInfo(MonitorFromPoint((0,0)))
workArea = monitorInfo.get("Work")
screenAvailableWidth = workArea[2]
screenAvailableHeight = workArea[3]
#Create a tkinter window
from tkinter import Tk
window = Tk()
#Set new window height & width
#--------------------------------------------
#----- HERE. What needs to change here? -----
#--------------------------------------------
windowWidth = screenAvailableWidth
windowHeight = screenAvailableHeight
#--------------------------------------------
#Show debug info
print("")
print("screenAvailableWidth:",screenAvailableWidth,
" screenAvailableHeight:",screenAvailableHeight)
print("windowWidth:\t",windowWidth," windowHeight:\t",windowHeight)
#Set the new window to upper left corner and height &
# width of screen
window.geometry("{}x{}+0+0".format(windowWidth,windowHeight))
#Show the window
window.mainloop()
I GOT IT! The trick is that as long as the window's visible (even if it's somewhere offscreen), you can do this:
titlebarHeight = window.winfo_rooty() - window.winfo_y()
borderSize= window.winfo_rootx() - window.winfo_x()
And once you have those, you can adjust your desired window width and height to correct for the title bar and borders like this:
WindowWidth = WindowWidth - (borderSize * 2)
WindowHeight = (WindowHeight - titlebarHeight) - borderSize
So, the code that ended up working in the end is this (which is complete - copy and paste this into your editor of choice and it should run as-is):
#Get screen height and width WITHOUT including the taskbar.
#This part works fine - I've tested the result and it's good.
from win32api import GetMonitorInfo, MonitorFromPoint
monitorInfo = GetMonitorInfo(MonitorFromPoint((0,0)))
workArea = monitorInfo.get("Work")
screenAvailableWidth = workArea[2]
screenAvailableHeight = workArea[3]
#Create a tkinter window
from tkinter import Tk
window = Tk()
#Set new window height & width
#--------------------------------------------
#----- HERE. This is what changed: -----
#--------------------------------------------
#Make window visible so we can get some geometry
window.update_idletasks()
#Calculate title bar and border size
titlebarHeight = window.winfo_rooty() - window.winfo_y()
borderSize= window.winfo_rootx() - window.winfo_x()
#Start with full available screen
windowWidth = screenAvailableWidth
windowHeight = screenAvailableHeight
#Adjust for title bar and borders
windowWidth = windowWidth - (borderSize * 2 )
windowHeight = (windowHeight - titlebarHeight) - borderSize
#--------------------------------------------
#Show debug info
print("")
print("screenAvailableWidth:",screenAvailableWidth,
" screenAvailableHeight:",screenAvailableHeight)
print("windowWidth:\t",windowWidth," windowHeight:\t",windowHeight)
#Set the new window to upper left corner and height &
# width of screen (after adjustment)
window.geometry("{}x{}+0+0".format(windowWidth,windowHeight))
#Show the window
window.mainloop()
(The breakthrough was examining all the properties mentioned in the suspected duplicate question (and it's comments and replies) here: tkinter window get x, y, geometry/coordinates without top of window
That question didn't really put the pieces together in a newbie-friendly way, nor did it have any usable sample code, so hopefully this will be of use to someone else in the future.)
To everyone who commented and offered solutions for me, thank you! I really appreciate you taking the time to do so. :-)
Instead of using monitorInfo you can use winfo_screedwidth() and winfo_screenheight().
This is how to do it:
windowWidth = window.winfo_screenwidth
windowHeight = window.winfo_screenheight
window.geometry("%sx%s" %(screenWidth, screenHeight)
You can use window.overrideredirect(True) to get rid of the task bar. It will also get rid of the bar at the top, so you will have to use alt+f4 to exit out of the window.
Also, these options are optional but will certainly make your code more clear and efficient by getting rid of possible errors which may occur when doing certain tasks with the code.
--You can stop reading if you want to--
Instead of from tkinter import Tk use import tkinter as tk. This means you can write tk.widget and not having to write out every widget you use. Also, if you use from tkinter import * you can use import tkinter as tk instead as it groups all attributes into tk. It will certainly clean up the attributes, and you will not having them together with all of the built in attributes
Also, get all of your widgets into a class. You can do this like so:
class Name(tk.Frame):
Inside it you need to write the __init__ function:
def __init__(self, master, **kwargs): #Feel free to add any extra parameters
Inside the __init__ function you write:
super().__init__(master, **kwargs)
The class makes your code neat and tidy while the __init__ and super() are needed for whenever you make a function.
Also, you can use the __name__ == "__main__" if condition to stop the code from running when importing it to another script.
This is how to do this:
def func_name():
root = tk.Tk()
#Add any root titles, geometry or any other configurations here
app = Window(root) #Instead of Window, replace it with your class name
app.pack(fill=tk.BOTH, expand=True)
#Add any app configurations here
root.mainloop()
if __name__ == "__main__":
func_name()
All these features, you can include to make your code neater.

How can tkinter detect width of task bar on windows so that fullscreen doesn't cover the taskbar?

I am trying to make a fullscreen window with tkinter but the window covers the whole screen including the windows taskbar.How do i make the window fit nicely into the screen without covering the taskbar? Here is my source code:
from tkinter import*
my_window = Tk()
my_window.title("Demo")
screen_width = my_window.winfo_screenwidth()
screen_height = my_window.winfo_screenheight()
x = (screen_width /2) - (width_of_window/2)
y = (screen_height/2) -(height_of_window/2)
my_window.geometry("%dx%d+0+0"%
(my_window.winfo_screenwidth(),my_window.winfo_screenheight())
my_window.mainloop()
I am coding in windows 10 using vs code.
This seems to be a difficult task. The easiest way I have found is to:
my_window.wm_state('zoomed')
This corresponds to maximized, but not fullscreen. This does not seem to work on all platforms.
Also see tkinter python maximize window

Tkinter window not filling screen in zoomed state on secondary display

I'm building a small python 3 tkinter program on windows (10). From a main window (root) I'm creating a secondary window (wdowViewer). I want it to be full screen (zoomed) on my secondary display. The code below works on my main setup with two identical screens. If I however take my laptop out of the dock and connect it to (any) external display, the new window only fills about 2/3 of the secondary display.
Two things to note:
- The laptop and external monitor have same resolution.
- The window is appropriately zoomed when overrideredirect is set to 0.
mon_primary_width = str(app.root.winfo_screenwidth()) # width of primary screen
self.wdowViewer = Toplevel(app.root) # create new window
self.wdowViewer.geometry('10x10+' + mon_primary_width + '+0') # move it to the secondary screen
self.wdowViewer.wm_state('zoomed') # full screen
self.wdowViewer.overrideredirect(1) # remove tool bar
app.root.update_idletasks() # Apply changes
After two days of experimenting I finally found a fix.
Consider the following example: Making a toplevel zoomed, works fine on any secondary display when using the following code:
from tkinter import *
# Make tkinter window
root = Tk()
sw = str(root.winfo_screenwidth())
Label(root, text="Hello Main Display").pack()
# Make a new toplevel
w = Toplevel(root)
w.geometry("0x0+" + sw + "+0")
w.state('zoomed')
w.overrideredirect(1)
Label(w, text='Hello Secondary Display').pack()
root.mainloop()
However, in my code I'm making a new Toplevel after running the mainloop command. Then, the issue arises. A code example with the issue:
from tkinter import *
# New Tkinter
root = Tk()
sw = str(root.winfo_screenwidth())
# Function for new toplevel
def new_wdow():
w = Toplevel(root)
w.geometry("0x0+" + sw + "+0")
w.state('zoomed')
w.overrideredirect(1)
Label(w, text='Hello Secondary Display').pack()
# Make button in main window
Button(root, text="Hello", command=new_wdow).pack()
root.mainloop()
Problem: The bug is only present if the DPI scaling in Windows is not set to 100%. Hence, there seems to be a bug in how tkinter handles the DPI scaling subsequent to running mainloop. It does not scale the window properly, but Windows is treating it as if it does.
Fix: Tell Windows that the app takes care of DPI scaling all by itself, and to not resize the window. This is achievable using ctypes. Put the following code early in your python script:
import ctypes
ctypes.windll.shcore.SetProcessDpiAwareness(2)
Hopefully others will find the solution helpful. Hopefully, someone may explain more of what is going on here!

Tkinter window outside desktop

How can I show a window created with Tkinter.Tk() outside visible screen? I need to make it much bigger than the desktop size, and show part of it defined by coordinates.
Use Tk.geometry with desired width, height and negative position.
from Tkinter import * # from tkinter import * (In Python 3.x)
root = Tk()
root.geometry('3000x3000+-100+-100')
root.mainloop()
I tested this on Ubuntu 12.04 (gnome) and Window 7.
In Ubuntu, it work well.
In Windows, negative position works, but width, height higher than resolution ignored.
Another possible way is to insert a frame and resize that, eg:
import tkinter as tk
root = tk.Tk()
frame = Frame(root, width = 1000, height = 1000)
frame.pack()
root.mainloop
The size of your window will then be determined by the frame, although the answer already given works just fine too

Categories