Fixing the place of a Tkinter window (not a widget) - python-3.x

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.

Related

Why does a borderless Kivy Window shift content down and to the right?

Using Kivy, I want to remove the default border from the App window (removing the close, minimize and maximize buttons). Based on the Kivy docs, I want to set the borderless value of my Window to True. However, doing so moves the content of my window down and to the right, exposing the black background color on the top and left sides of the window.
Screenshot of Window with borderless=False
Screenshot of Window with borderless=True
In the above images, the white within the window is coming from the Window.clearcolor, and the black in the borderless=True image is what I want to remove, or overlay with the rest of my content.
In the following snippet I have removed all the code that makes up the inner widgets of the kivy App, replacing them with an empty GridLayout to show where the content will be.
from kivy.app import App
from kivy.uix.gridlayout import GridLayout
from kivy.core.window import Window
class MyApp(App):
def build(self):
self.title = 'My App'
Window.clearcolor = (1, 1, 1, 1)
Window.size = (300, 430)
Window.borderless = True # This is what is being changed
return GridLayout()
if __name__ == '__main__':
MyApp().run()
I have read the answers to similar questions regarding removing the default Kivy window border and how to position a borderless Kivy window.
Can anyone help diagnose how to shift the contents of my window back to the upper left corner when borderless is set to True?
Note: This is my first Stackoverflow question, please let me know how to improve it if need be!
Well, I'm not sure what the exact issue was, but after troubleshooting several different things within PyCharm (where my original project files were held), on a whim I tried opening the same project with Sublime and the issue is no longer present. When I run the identical code in Sublime, I get the intended result:
Beautiful! Just how I wanted it. =) I'm sure I somehow goofed up the Kivy settings in Pycharm somehow without realizing it, maybe something with the builder strings? I'm honestly at a loss. But I suppose if by any off chance someone else comes across this, switch up your IDE for a clean slate and give it another go.

Hide tk window when using filedialog

I'm trying to use filedialog.asksavefilename to get a save file path. I am running this code in the IDLE shell and it's a text based interface. This is the function to get the save path:
def getPath():
root=tk.Tk()
root.lift()
root.attributes('-topmost',True)
root.after_idle(root.attributes,'-topmost',False)
path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=(("Text Documents", "*.txt"),))
root.destroy()
The dialog opened behind other windows, so I used this to make the dialog appear at the front. This works, but there is still an empty window behind it which I don't want. I've tried using root.withdraw() but this just hides everything. I'd like to have only the file dialog open without the empty tk window. Any ideas as to how to do this?
I've found a way to achieve the desired effect:
def getPath():
root=tk.Tk()
root.overrideredirect(True)
root.attributes("-alpha", 0)
path = filedialog.asksaveasfilename(defaultextension=".txt", filetypes=(("Text Documents", "*.txt"),))
root.destroy()
I've removed all of the unnecessary lift and topmost parts - they didn't help. I used root.overrideredirect(True) to remove the title bar and root.attributes("-alpha", 0) to make the window 100% transparent, so you can't see it. The only drawback is that the file dialog window flashes when it opens, but that's not too much of a problem.
from tkinter import Tk
from tkinter.filedialog import asksaveasfilename
def get_path():
root = Tk()
root.withdraw()
path = asksaveasfilename()
root.destroy()
return(path)
print(get_path()) # to verify expected result
Is this the behavior you're looking for? Hope this helps.

Make a Toplevel window take up the entire monitor space?

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)

Closing a tkinter Entry Widget without killing the program

I am currently stepping through the tkinter tutorial at python-course.eu. Is it possible to close an entry widget without killing the program? What I am trying to do is incorporate the tkinter entry box into a pygame program such that the program asks for the players name via an entry box and then closes once the text has been entered. The game should then continue. Is this possible?
What I would like to do is:
-create a pygame surface
-open a tkinter entry widget on top of that surface
-get the users name
-close the tkinter widget
-write text using pygame onto the surface that incorporates the user's name
What is stumping me is the fact that the tkinter examples on python-course.eu all end with a mainloop() statement while I would like pygame to have an event loop so that I can expand the program. I anticipate that the widget creation would occur prior to dropping into the event loop. This is where I am stuck :-(
rather than trying to mix two GUI libraries in the same window, if a prompt is acceptable you could use:
import tkinter as tk
from tkinter import simpledialog
root = tk.Tk() # needed to prevent extra window being created by dialog
root.withdraw() # hide window as not needed
username = simpledialog.askstring('Username', 'Enter username:')
root.destroy()

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