I'm trying to make a window and because I want to hide the window bar at the top of the screen:
import ctypes
mainWindow = tkinter.Tk()
screen = ctypes.windll.user32
width = int(screen.GetSystemMetrics(0))
height = int(screen.GetSystemMetrics(1))-40
mainWindow.geometry(str(width)+'x'+str(height)+'-0-32') # <----------- signaled line
The problem is that I'm not being abble to get a full width window.
In the signaled line if I write (-0):
mainWindow.geometry(str(width)+'x'+str(height)+'-0
... I get a lack to cover in the right side of the screen.
In the signaled line if I write (+0):
mainWindow.geometry(str(width)+'x'+str(height)+'+0
I get a lack to cover in the left side of the screen.
To hide the window bar (regardless of size) you can call root.overrideredirect(True).
I frequently use this code to fullscreen:
root.overrideredirect(True)
root.geometry('{0}x{1}+0+0'.format(root.winfo_screenwidth(), root.winfo_screenheight()))
you can obviously modify this to format it to just the screenwidth and a constant pixel size height (though I'm unsure of why you'd want to do that)
Related
How can I do (if any user try to resize window width will automatically resize window height too with aspect ratio. That's mean user can't be able to resize only one size. changing one side size will change another side too.)?
(After closely reading the comment you made under your question describing how you wanted this to work, I've revised the code once again to make it so.)
You can do it by handling '<Configure>' events in an event handler bound to the root window. This is tricky because when you add a binding to the root window, it also gets added to every widget it contains — so there's a need to be able to differentiate between them and the root window in the event handler. In the code below this is done by checking to see if the event.widget.master attribute is None, which indicates the widget being configured is the root window, which doesn't have one.
The code creates the root window and binds root window resizing events to an event handler function that will maintain the desired aspect ratio. When a resize event of the root window is detected, the function checks the aspect ratio of the new size to see if it's has the proper ratio, and when it's doesn't it blocks further processing of the event, and manually sets the window's size to a width and height that does.
import tkinter as tk
WIDTH, HEIGHT = 400, 300 # Defines aspect ratio of window.
def maintain_aspect_ratio(event, aspect_ratio):
""" Event handler to override root window resize events to maintain the
specified width to height aspect ratio.
"""
if event.widget.master: # Not root window?
return # Ignore.
# <Configure> events contain the widget's new width and height in pixels.
new_aspect_ratio = event.width / event.height
# Decide which dimension controls.
if new_aspect_ratio > aspect_ratio:
# Use width as the controlling dimension.
desired_width = event.width
desired_height = int(event.width / aspect_ratio)
else:
# Use height as the controlling dimension.
desired_height = event.height
desired_width = int(event.height * aspect_ratio)
# Override if necessary.
if event.width != desired_width or event.height != desired_height:
# Manually give it the proper dimensions.
event.widget.geometry(f'{desired_width}x{desired_height}')
return "break" # Block further processing of this event.
root = tk.Tk()
root.geometry(f'{WIDTH}x{HEIGHT}')
root.bind('<Configure>', lambda event: maintain_aspect_ratio(event, WIDTH/HEIGHT))
root.mainloop()
I want to set default tkinter screen and not full screen in tkinter.Thank you
root.geometry("500x100") #Width x Height
Use this code to change your Tkinter screen size. Here root is the main window, geometry() is the function used to change screen size. 500 is the width and 100 is the height
its very easy you just need to set the with and heigth of the window by
root.geometry("400x900") # this .geometry() takes a string in the form of width x heigth
You have various arguments for your Tkinter window :
window.attributes("-fullscreen", True)
Changing it to False will disable fullscreen mode, True will activate it
window.geometry("1400x700")
You can set the default size of your GUI with this, but the user will be able to resize it classically
window.minsize(200, 200)
This one will set the minimum size of your GUI, past it, the user will not be able to reduce the window any further. If you set it to the size of your window, you disable the resizing.
Apologies for not being very clear the first time round.
I am looking for a way to specify the size of "fullscreen" for a window. Is there a way for me to do this?
I have a window that opens off fullscreen mode. When I put the window in full screen mode, the bottom of the window goes behind the taskbar. Is there a way that I can avoid this.
Note that I don't know the size of the screen or taskbar beforehand.
you can simply write:
from tkinter import *
root = Tk()
height = root.winfo_screenheight()
width = 400 #or whatever you want the width to be
root.resizable(height = height, width = width)
(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.
Using a bit of modified code I found on the web for creating a generic Tkinter splash screen, I tried to to create a transparent splash screen kind of thing with a .png. I know this code will only work with Windows and I am fine with that.
However, I notice there is flickering (Canvas area is black before it draws the picture) with the image when it draws on the screen. I don't know very much about it but I suspect it has to do something with the buffering of the image after googling and reading. I also read that canvas supports double buffering so the flickering shouldn't be happening so maybe it's the Top Level widget or something.
In any case is there any fix to this? I'd really like to continue using Tkinter for this and it would be a huge letdown not to be able to get rid of the flickering. Here is the code I am using below.
from Tkinter import *
import ttk
from PIL import Image, ImageTk
import time
class Splash:
def __init__(self, root, filename, wait):
self.__root = root
#To use .pngs or .jpgs instead of just .bmps and .gifs, PIL is needed
self.__file = ImageTk.PhotoImage(Image.open(filename))
self.__wait = wait + time.clock()
def __enter__(self):
# Hide the root while it is built.
self.__root.withdraw()
# Create components of splash screen.
window = Toplevel(self.__root)
#Set splash window bg to transparent
window.attributes('-transparent', '#FFFFFE')
#Set canvas bg to transparent
canvas = Canvas(window,bg="#FFFFFE")
splash = self.__file
# Get the screen's width and height.
scrW = window.winfo_screenwidth()
scrH = window.winfo_screenheight()
# Get the images's width and height.
imgW = splash.width()
imgH = splash.height()
# Compute positioning for splash screen.
Xpos = (scrW - imgW) // 2
Ypos = (scrH - imgH) // 2
# Configure the window showing the logo.
window.overrideredirect(True)
window.geometry('+{}+{}'.format(Xpos, Ypos))
# Setup canvas on which image is drawn.
canvas.configure(width=imgW, height=imgH, highlightthickness=0)
canvas.pack()
# Show the splash screen on the monitor.
canvas.create_image(imgW // 2, imgH // 2, image=splash)
window.update()
# Save the variables for later cleanup.
self.__window = window
self.__canvas = canvas
self.__splash = splash
def __exit__(self, exc_type, exc_val, exc_tb):
# Ensure that required time has passed.
now = time.clock()
if now < self.__wait:
time.sleep(self.__wait - now)
# Free used resources in reverse order.
del self.__splash
self.__canvas.destroy()
self.__window.destroy()
# Give control back to the root program.
self.__root.update_idletasks()
self.__root.deiconify()
if __name__ == '__main__':
#thread2 = myLazyDoStuffThread()
root = Tk()
with Splash(root,'splash.png',3):
myprog = ApplyGUIAndOtherThings(root)#,thread2)
root.mainloop()
A rule of thumb you should follow is to never put a call to sleep in a GUI. It does exactly what it says, it causes your whole application to sleep. This means that the GUI is not able to redraw itself, and is likely the cause of your flicker.
If you want a window to be destroyed after a period of time, use the after method. For example:
delta = (self.__wait - now) * 1000
self.after(delta, self.close)
You'll need to define self.close to destroy the window.
This gives you an opportunity to add a little "fade away" effect if you like. You do this by checking to see if the alpha of the splash screen is below some threshold (say, 10%) and destroy it. If it's not, reduce the alpha by 10% and call the function again in 100 ms.