Can't find this anywhere else on stack overflow.
I want to create a dialog box (on top of my main window) in tkinter that has message, a text input field and some custom buttons.
I know I can do
import tkinter as tk
from tkinter import simpledialog
master = tk.Tk()
user_input = tk.simpledialog.askstring("title", "message")
and then take the user_input from there. However, how can I make the buttons have custom text and also bind them to my own functions?
Otherwise, I was thinking of making my own dialogbox class. But that's a lot of work. Is there any way I can do this natively using any of tkinter' modules?
Regards
Hugo.
Related
I am learning about Tkinter and was wondering if it would cause errors if I did the following:
import tkinter as tk #import modules
from tkinter import ttk
parent=tk.Tk() #create first instance
card1="k spades"
card2="k diamonds"
comboform=ttk.Combobox(parent,textvariable='form',values=[card1,card2,"both","neither"])#create combobox input form
comboform.grid(row=0,column=0)#added to grid
parent.geometry("200x200")
parent.mainloop()#displays tkinter window
#window exited
parent=tk.Tk()#new instance created
label=tk.Label(parent,text="hi")#label produced
label.pack()#added to window
parent.mainloop()
If I click the exit cross is that the same as parent.destroy(); is that good practice? I know you're only supposed to run mainloop() once and have one Tk() instance but if it's destroyed is it going to cause problems? It's not like I'm creating a class the produces a Tk() instance, where there's a risk of multiple instances existing at once.
I am hoping to, eventually, have an application running in the IDLE and then have a tkinter window appear, presenting an input widget of some kind. After the user gives their input, the window would close and the user would continue in the main window. But could I then do it again, opening new windows (like the above code) on the provision that the instance of Tk() is destroyed each time?
If you've destroyed the root window and then create a new one, that's perfectly fine.
The problem with creating multiple instances of Tk is that most people don't understand what that actually does. Having multiple instances of Tk is fine as long as you realize that they operate in completely memory spaces and widgets and bindings in one can't interact with widgets and bindings in the other.
All of that being said, the best practice is to create a single root window at the start of the program, and it stays alive until the program exits. If you need additional windows, the best practice is to create instances of Toplevel.
I'm using Tkinter with a GUI using a button inside the root window.
I also want to use a Button inside a MatplotLib graph that allows me to exit the graph (and potentially for other uses in the future).
The only problem is that they both use the same label Button. These two labels have different syntax so I can only either have Tkinter buttons or Matplotlib buttons.
I'm sure this is a very amateur question but is there a way to specify that this Button is a tkinter button while another Button is a matplotlib button?
Here's an example of the code:
from matplotlib.widgets import Slider, Button, RadioButtons
from tkinter import *
btn = Button(root, text="Plot", command=graph).pack()
Found the answer but this might be helpful to some people
You can instead use
import tkinter as tk
and then everytime you want to you a tkinter function you specify it by writing "tk." before it.
E.g.:
tk.Button
in this case and it will specifically use the tkinter version of the Button
I'm currently working with Tkinter and Python 2.7 on Linux and I was wondering if there was a way to remove the TK() window border frame and title bar without using overrideredirect(1).
I have my own close button and overrideredirect(1) presents me with a few issues that I can't accept:
GUI always on top
can't iconify then deiconify properly
no keyboard input so can't type into fields (see python tkinter overrideredirect; cannot receive keystrokes (Linux))
I can't use attributes("-fullscreen", True) as the titlebar and borders remain.
The window decoration is all handled by the window manager so what you are trying to do is find a way to tell the window manager to decorate your window differently from a standard application window. Tk provides overrideredirect to have the window manager completely ignore this window but we can also use Extended Window Manager Hints to declare the intended use of this toplevel window to the window manager. This is done for instance for tooltip and splashscreen windows to allow the manager to provide minimal decoration and possibly special animations.
In your case, adding a 'splash' hint should do what you want
root = tk.Tk()
root.wm_attributes('-type', 'splash')
You will need Tk 8.5 or above for this.
You must give your root window name before your command.
Like this:
from tkinter import *
root=Tk()
root.wm_attributes('-fullscreen','true')
root.mainloop()
I have multiple buttons in my tkinter 8.5 GUI (on Windows 7). I want whatever button is focused on (tabbed over) to be selected when the user hits Enter. I know I have to bind '<Return>', but I need the rest of the gaps filled in.
Thanks in advance!
Assuming you want this to be universal to all applications in the root window you could do something similar to this.
def clickButton():
widget = root.focus_get()
if widget != root:
widget.invoke()
root = Tkinter.Tk()
root.bind("<Return>", clickButton)
root.mainloop()
That will run any command associated with the currently tabbed selection. If you want to limit it to certain buttons you can do type-checking inside of the method. Widget will be whatever widget is currently in focus via the tabbed selection. Also beware of a user hitting enter on certain widgets that may not support the invoke method.
I'm working on a graphical app, and at the start of the run I'd like to ask the user a single configuration question. The graphical framework (Panda3D) has ugly default dialog boxes, so I'd like to use something like tkInter to provide a modal dialog. I tried this:
import Tkinter
import tkMessageBox
root = Tkinter.Tk()
# hide the root window
root.withdraw()
config.PLAY_MUSIC = tkMessageBox.askyesno( "My App",
"Would you like this app to play music from your iTunes collection?" )
root.destroy()
This does what I want it to, but it appears to route all further keyboard events to tkInter rather than my Panda3D app. I don't need to do anything further with tk after this dialog.
I can put the tk dialog into a separate app that chains onto mine, I suppose, but I'm wondering if there's a way to kill tk and get the keyboard back without exiting my app entirely.
Update: Tried root.quit(), which does seem to get the keyboard back, but I get a "Fatal Python error: PyEval_RestoreThread: NULL tstate" crash on exit from my program, which isn't ideal.
Have you tried:
grab_release(self)
Which does: Release grab for this widget if currently set.
Where "A grab directs all events to this and descendant
widgets in the application."
as in:
root.grab_release()
Hope you haven't tried this one.