Make a Toplevel window take up the entire monitor space? - python-3.x

I'm trying to make a tkinter Toplevel window to go full screen and take up the entire monitor space (going over the task bar as well). I am able to do this with the Tk() using the code: window.attributes("-fullscreen", True). But I know you can't have two instances of Tk() so I need to use a Toplevel and root.attributes("-fullscreen", True) does not work with Toplevel.
The code I have in place at the moment to make the Toplevel fullscreen is this:
window = Toplevel()
w = window.winfo_screenwidth()
h = window.winfo_screenheight()
window.geometry("%dx%d+0+0" % (w,h))
But this does not even go into a proper fullscreen mode as the left side of the interface does not reach the edge of the screen.
How can I get a Toplevel window to take up the entire space of the screen like a Tk() window can?

I found a work around to this issue. What I did was I set the Tk() interface to take up the entire screen, and I placed a frame on top of it and made it fit the Tk(). That way I could put the desired widgets on the frame and when I'm done, destroy the frame and reset the size of the Tk() frame.

This is a possible way to solve fullscreen trouble:
finestra1= Toplevel()
wf1= finestra1.winfo_screenwidth()
hf1= finestra1.winfo_screenheight()
A = str(wf1)
B = str(hf1)
finestra1.geometry(A+"x"+B)

Related

Fixing the place of a Tkinter window (not a widget)

This is the code for the window:
import tkinter as tk
root = tk.Tk()
root.resizable(False, False)
root.geometry('200x200+400+400')
This window can be dragged to move from its place. How to to fix it in its place?
Do you mean that the window can be a non-fullscrean size, but it can't be dragged around like another application? I think that is on the operating system side of the problem. What are you making? Maybe there is a workaround.
It is possible however to make it forced fullscreen. For that Check here: https://www.tutorialspoint.com/how-to-display-full-screen-mode-on-tkinter#:~:text=Tkinter%20displays%20the%20application%20window,fullscreen%2C%20toolwindow%2C%20and%20topmost.

How to close a particular window without closing the whole app in Tkinter?

I'm creating a Tic-Tac-Toe program using tkinter, in which I would like to take the name of the user using entry and the next name to be given in a separate window, but before that I would like to automatically close the previous window.
I used a common variable called root (mainloop also) for displaying all the windows. Once I destroy the root, the whole program stops. Should I name a separate variable with tk.Tk() to proceed and use it in other windows? I just can't understand.
Can anyone help me...
Yes, destroying the root will close the entire app.
If you want to close windows while keeping the app running, you can use a tk.Toplevel to pop a window open, and be able to close it while continuing other operations.
maybe like this:
import tkinter as tk
def popup():
p = tk.Toplevel(root)
p.title('popup')
tk.Label(p, text='I will self destroy in 3 seconds').pack()
p.after(3000, p.destroy)
root = tk.Tk()
btn = tk.Button(root, text='pop a new window', command=popup)
btn.pack()
root.mainloop()

Weird white Stripe appearing next to tkinter scrollbar

So while 'designing' my tkinter application i noticed this white stripe appearing next to the scrollbar there:
It is not disappearing when the scrollbar gets to an active state but it is definetly part of the Scrollbar itself because there is nothing under it in my programm which has a white background.
It seems to appear no matter if I use grid or pack. In this case I use grid - here the little extract of my code:
class App(Tk):
def __init__(self):
#other stuff
self.hvf=hvFrame(self,sticky=EW,showfocus=S,bg='white',padx=5,pady=5)
self.hvf.grid(row=1,column=0,columnspan=2,sticky=NSEW,pady=5,padx=(0,5))
sb=Scrollbar(self,orient=VERTICAL,command=self.hvf.yview,bd=0,highlightthickness=0)
sb.grid(row=1,column=2,sticky=NSEW,pady=5)
self.hvf.config(yscrollcommand=sb.set)
If you ned more, then here you go. (Should not be executable for you because you do not have the extras file but you should still be able to understand it.)
EDIT:
A little reproduceable example:
from tkinter import Tk,Frame,Scrollbar,VERTICAL,NS
root = Tk()
frame = Frame(root,height=300,width=500)
frame.grid(row=0,column=0,padx=(0,5),pady=5)
sb = Scrollbar(root,orient=VERTICAL)
sb.grid(row=0,column=1,sticky=NS,pady=5)
root.mainloop()
After testing a few things like changing the windows theme or changing the root and frame background to black the while line still comes up. I cannot be 100% sure but I believe this is due to fact that tkinter on Windows pulls the scrollbar design from Windows itself and it is simply part of that design. It may be a design choice to give the scroll bar some visual depth. That said you cannot do anything to change the design of the scrollbar within a Windows environment so you as stuck with this unless you write a custom scrollbar.
Example code:
import tkinter as tk
root = tk.Tk()
root['bg'] = 'black'
frame = tk.Frame(root, height=300, width=500, background='black')
frame.grid(row=0, column=0)
sb = tk.Scrollbar(root, orient=tk.VERTICAL)
sb.grid(row=0, column=1, sticky=tk.NS)
root.mainloop()
Results from overlay of white and black backgrounds:
Below is the code I use for a custom scrollbar (but did not write myself). You can find the post where I got the code here.

How to fix tkinter cursor vertical offset while in full screen on macOS?

I am having a problem with Tkinter detecting the wrong cursor position when the application is in fullscreen mode on macOS.
I have created a Python 3 application with a Tkinter GUI on macOS (Mojave). The application works well until the green full screen button is pressed. After this the menu bar is hidden as expected, but the window only expands to 2560x1395 on a 2560x1440 display. The interface also detects the mouse cursor above where it appears on the screen, which makes the application impossible to use. I have tried forcing the application to expand to the full height of 1440, but it immediately changes back to 1395.
Here is a minimal case demonstrating the problem:
import tkinter as tk
def test():
print("Test")
root = tk.Tk()
tk.Button(root, text="Test", width=20, command=test).pack()
root.mainloop()
While in normal windowed mode, clicking the button causes "Test" to be printed. While in full screen the user must click below the button for the click to be registered. Exiting the application while in full screen mode also causes a segmentation fault.
In my application, clicking where the red dot is causes the OptionMenu to open:
The applications which support macOS properly opens in a separate Desktop tab when used in fullscreen. As far as I observed this is not case with tkinter, the window expands to fit completely with the screen size onto the main Desktop tab.
Why there is an offset when in fullscreen mode?
The offset is of the titlebar which hides in fullscreen mode but doesn't register and shifts all the widgets accordingly. That's why mouse clicks register + 24 (height of the titlebar) from the click. To avoid this we use root.attributes('-fullscreen', 1).
To exit fullscreen we can use <Escape> bind as Escape key in most application is to exit from fullscreen like in Safari. You can also use a Button.
root.bind('<Escape>', lambda e: root.attributes('-fullscreen', 0))
I couldn't find an event handler for fullscreen mode on Mac so I used <Configure> with condition root.attributes('-fullscreen') to check if the user clicked for fullscreen or not.
This is what I come up with.
from tkinter import *
root = Tk()
Button(root, width=20, text='Hello').pack()
def full_screen(evt=None):
# checks if the window is in fullscreen
if root.attributes('-fullscreen'):
root.attributes('-fullscreen',1)
# Remove the borders and titlebar
root.overrideredirect(True)
root.overrideredirect(False)
root.bind('<Configure>', full_screen)
# Escape bind to exit fullscreen.
root.bind('<Escape>', lambda e: root.attributes('-fullscreen', 0))
root.mainloop()
This issue is known for 6 months now, and Apple is doing nothing about it, now the fun fact is the logic display is fine (if you record your screen or if you screen share it doesn't happen) it only happens on the physical screen, and it only happens on MBP 16"
I am now over the fact that there is a hardware issue with the (some) MBP 16" video cards and Apple is just playing dumb.
If it helps, having your screen without scale or with "double" scale works fine, it's in the 3 intermediate scales that the issue presents itself

Python Tkinter Clickable Text?

I'm wondering if there's a way to make clickable text in Tkinter. Maybe like you would see on a title screen of a game, and where you hover your mouse over the text and it changes color/hightlights itself. All I need the click to do is execute another function.
Are either of these things possible? Thanks!
you are looking for tkinter's events:
tk_widget.bind("<Button-1>",CALLBACK)
The call back needs to take an event argument which is a dictionary containing information about what triggered the event.
This can run into issues with widgets that overlap such as windows in a canvas or labels sometimes triggering the callback for the window behind it.
For hovering the mouse over a widget the event is called "<Enter>" and moving mouse out of widget region is called "<Leave>" for highlighting text effect, if you just want to capture a click anywhere on a window then on the root call root.bind_all("<Button-1>",CALLBACK)
source: http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html
http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/events.html
example:
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
def change_case(event=None):
new_text = str.swapcase(lab["text"])
lab.config(text=new_text)
def red_text(event=None):
lab.config(fg="red")
def black_text(event=None):
lab.config(fg="black")
root = tk.Tk()
lab = tk.Label(root,text="this is a test")
lab.bind("<Button-1>",change_case)
lab.bind("<Enter>",red_text)
lab.bind("<Leave>",black_text)
lab.grid()
root.mainloop()
hope this helps :)

Resources