i wrote bellow code in python 3.6.2 by tkinter,I want the cursor move to password textbox when user press Enter key in username textbox.
from tkinter import *
class Application(Frame):
def __init__(self,master):
super(Application, self).__init__(master)
self.grid()
self.create_main()
def create_main(self):
print("testing")
self.title = Label(self, text=" Stuck In The Circle ")
self.title.grid(row=0, column=2)
self.user_entry_label = Label(self, text="Username: ")
self.user_entry_label.grid(row=1, column=1)
self.user_entry = Entry(self)
self.user_entry.grid(row=1, column=2)
self.pass_entry_label = Label(self, text="Password: ")
self.pass_entry_label.grid(row=2, column=1)
self.pass_entry = Entry(self)
self.pass_entry.grid(row=2, column=2)
self.user_entry = Entry(self, justify="right")
self.pass_entry = Entry(self, justify="right")
self.sign_in_butt = Button(self, text="Sign In",command = self.logging_in)#SIGN IN BUTTON
self.sign_in_butt.grid(row=5, column=2)
def logging_in(self):
user_get = self.user_entry.get()
pass_get = self.pass_entry.get()
root = Tk()
root.title("Stuck in the Circle")
root.geometry("400x100")
app = Application(root)
root.mainloop()
How can do it?
This is actually a lot simpler than I expected it to be.
We can use .bind() to get a callback on the <Return> event. This means that every time the return character is pressed whenever the defined widget is in focus we get a callback.
In order to get it to cycle to the next widget we can use this answer from Bryan Oakley:
def focus_next_window(event):
event.widget.tk_focusNext().focus()
return("break")
text_widget=Text(...) text_widget.bind("<Tab>", focus_next_window)
Important points about this code:
The method tk_focusNext() returns the next widget in the keyboard
traversal hierarchy. the method focus() sets the focus to that widget
returning "break" is critical in that it prevents the class binding
from firing. It is this class binding that inserts the tab character,
which you don't want.
So, applying the same logic in our situation we can use something like the below:
from tkinter import *
class App:
def __init__(self, root):
self.root = root
self.entry1 = Entry(self.root)
self.entry2 = Entry(self.root)
self.entry1.pack()
self.entry2.pack()
self.entry1.bind("<Return>", self.callback)
def callback(self, event):
event.widget.tk_focusNext().focus()
root = Tk()
App(root)
root.mainloop()
Related
I am quite new with Tkinter and am trying to create a new window using this script while keeping the current window but i am get the error
_init_() missing 1 required positional argument: 'parent'. I am not really sure what the reason is but I am assuming that the command function for my button isn't working the way I want it.
The script currently looks something like this:
from tkinter import simpledialog
from tkinter import *
class Additional(simpledialog.Dialog):
def body(self, master):
#input fields
Label(master, text="Picture 3 Path:").grid(row=1)
#input fields for tags
#add as needed
self.e1 = Entry(master)
self.e1.grid(row=1, column=1, ipadx=150)
return self.e1 # initial focus
def apply(self):
first = self.e1.get()
self.ttag1 = (first)
class Initial(simpledialog.Dialog):
def body(self, master):
#input fields for username and passwords
Label(master, text="Usernames:").grid(row=1),
self.e1 = Entry(master)
self.b1 = Button(master, text = "Add More", bg= 'grey', command= Additional)
self.b1.grid(row=6, column=2, ipadx=75)
self.e1.grid(row=1, column=1, columnspan=2, ipadx=50)
return self.e1 # initial focus
def apply(self):
first = self.e1.get()
self.tag1 = (first)
root = tk.Tk()
root.withdraw()
d = Initial(root)
toor = tk.Tk()
toor.withdraw()
I have tried changing it up but it seems that it's not working right. Any ideas?
When calling the Additional class through the button command, you are not specifying what the parent root should be, and therefore the class fails to initiate. You can solve this by passing the master using a lambda
self.b1 = Button(master, text="Add More", bg='grey', command=lambda: Additional(master))
I cannot get my code to pass the pop up text entry to a global variable i am also attempting to set this global variable as the default text in the entry field in all future instances.
Pop up -> Enter Filepath -> accept&close -> Re-open shows last filepath present as default -> if changed new filepath entry becomes default in future.
import tkinter as tk
from tkinter import ttk
from tkinter import *
master = tk.Tk()
Var1 = StringVar()
Filepath_Var = None
def A_Connect():
root = Tk()
root.title("Entry Field")
def entry_field():
global Filepath_Var
Filepath_Var = Var1.get()
tk.Label(root, text="filepath: ").grid(row=0)
e1 = tk.Entry(root, textvariable=Var1)
tk.Label(root, text="Item Number: ").grid(row=1)
e2 = tk.Entry(root)
#e1.insert(0, r"C:\Users\zxy\ghj\iugf\Bea\something.xlsx")
e1.insert(0, Var1.get())
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
Button(root, text = 'Accept', command = entry_field).grid(row=3, column=1,
sticky=W, pady=4)
root.mainloop()
note = ttk.Notebook(master)
tab1 = tk.Frame(note)
canvas7 = Canvas(tab1, width=520, height=350)
canvas7.pack()
A_Button = tk.Button(tab1, text="A",
width=12, height=3,command=A_Connect, anchor = 'w')
A_Button_Window = canvas7.create_window(20, 120, anchor = 'sw',
window = A_Button)
note.add(tab1, text = " Main ")
note.pack()
master.mainloop()
As a follow up to your earlier question, I encapsulated an example of the (bare bones) desired behavior in two classes:
The main App consists of a button that launches an entry popup; upon filling the fields and accepting, the value in the entry is provided to the App, and the popup closed.
The value entered is stored by the App, and used to populate the entry field of the entry fields in successive popups.
You will probably want to add confirmations and verifications before changing the defaults, and closing the popup, but here, you have the basic skeleton to attach this to.
import tkinter as tk
class PopUpEntry(tk.Toplevel):
def __init__(self, master, default_value=None):
self.master = master
super().__init__(self.master)
if default_value is None:
self.default_entry = 'C:*****\somthing.xlsx'
else:
self.default_entry = default_value
self.title("Entry Field")
tk.Label(self, text="Filepath: ").pack()
self.e1 = tk.Entry(self)
self.e1.insert(0, self.default_entry)
self.e1.pack()
tk.Button(self, text = 'Accept', command=self.entry_field).pack()
def entry_field(self):
self.default_entry = self.e1.get()
self.master.provide_entry_value(self.default_entry)
self.destroy()
class App(tk.Tk):
def __init__(self):
super().__init__()
self.pop_entry = tk.Button(self, text='launch entry', command=self.launch_entry)
self.pop_entry.pack()
self.default_entry_value = None
self.mainloop()
def launch_entry(self):
PopUpEntry(self, self.default_entry_value)
def provide_entry_value(self, value):
self.default_entry_value = value
print(self.default_entry_value)
App()
NameError: name 'onOpen' is not defined
There is something wrong with the command function. I am not sure what I did wrong here. I had the code tested before the onOpen function and it works fine.
import tkinter as tk
from tkinter import filedialog
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.pack()
self.createWidgets()
def onOpen():
""" Ask the user to choose a file and update the values of label change button"""
button_label.set(filedialog.askopenfilename(filetypes = ()))
def createWidgets(self):
#instruction label
self.labelInstruct = tk.Label(self, text="Instructions:", padx=10, pady=10)
self.labelInstruct = tk.Label(self, text="All you have to do is insert the file and save it.\n The conversion is instant", padx=10, pady=10)
self.labelInstruct.pack()
#insertfile button
self.ifbut = tk.Button(self, text="Insert File", command=onOpen)
self.ifbut.pack()
button_label = tk.StringVar(self)
text = tk.Label(self, textvariable = button_label)
text.pack()
#save button
self.saveLabel = tk.Label(self, text="Save File", padx=10, pady=10)
self.saveLabel.pack()
self.saveButton = tk.Button(self)
self.saveButton.pack()
#quit button
self.quitButton = tk.Button(self, text='Quit',
command=self.quit)
self.quitButton.pack()
app = Application()
app.master.title('Sample application')
app.mainloop()
Seeing that there are many problems with the way this code is written I am only going to point out a few of them and tackle the main question from the OP.
Lets start with the fact that you need to define the main window with something like root = tk.Tk() and you also need to make sure all your methods in your class have the argument self as the first argument.
Also any variable you are defining also should have self so that the class can interact with it. This (button_label) for example should be self.button_label.
There is no reason to use return the way you are trying to in the onOpen(self): method. Return does not work like that. Return is there so you can return a value to something that is calling the function/method to be used for something else and is not for setting the value of something.
Note that I also add the root window variable to the app = Application(root) line. This lets us pass the main window into the class.
all and all the following should work for the onOpen(self): function but the rest still needs some work.
import tkinter as tk
from tkinter import filedialog
class Application(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.pack()
self.createWidgets()
def onOpen(self):
""" Ask the user to choose a file and update the values of label change button"""
self.button_label.set(filedialog.askopenfilename(filetypes = ()))
def createWidgets(self):
#instruction label
self.labelInstruct = tk.Label(self.parent, text="Instructions:", padx=10, pady=10)
self.labelInstruct = tk.Label(self.parent, text="All you have to do is insert the file and save it.\n The conversion is instant", padx=10, pady=10)
self.labelInstruct.pack()
#insert file button
self.ifbut = tk.Button(self.parent, text="Insert File", command = self.onOpen)
self.ifbut.pack()
self.button_label = tk.StringVar()
self.text = tk.Label(self.parent, textvariable = self.button_label)
self.text.pack()
#save button
self.saveLabel = tk.Label(self.parent, text="Save File", padx=10, pady=10)
self.saveLabel.pack()
self.saveButton = tk.Button(self.parent, text = "Save")
self.saveButton.pack()
#quit button
self.quitButton = tk.Button(self.parent, text='Quit', command=self.quit)
self.quitButton.pack()
root = tk.Tk()
app = Application(root)
app.master.title('Sample application')
app.mainloop()
You need to return the function value as below:
def onOpen():
""" Ask the user to choose a file and update the values of label change button"""
return button_label.set(filedialog.askopenfilename(filetypes = ()))
I searched how to get the input and this should work but it doesnt...
i dont understand why it doesnt working... its start running and get stuck in the mainloop line... it shows nothing
from Tkinter import *
class GUI:
def __init__(self):
self.root = Tk()
self.label1 = Label(self.root, text="name")
self.label2 = Label(self.root, text="password")
self.entry1 = Entry(self.root)
self.entry2 = Entry(self.root, show="*")
self.button = Button(self.root, text="hello", command=self.printName)
self.button.pack()
self.label1.grid(row=0, sticky=W) # N, S, E, W
self.label2.grid(row=1, sticky=E)
self.entry1.grid(row=0, column=1)
self.entry2.grid(row=1, column=1)
self.c = Checkbutton(self.root, text="forgot my password")
self.c.grid(columnspan=2)
self.root.mainloop()
def printName(self):
print self.entry1.get()
hi = GUI()
The problem is that you are using both grid and pack for widgets that share the same parent. You can't do that -- you have to pick one or the other.
Also, to be pedantic you should ove the call of self.root.mainloop() outside of the __init__. The reason is that with it being inside, the object is never fully created because mainloop won't return until the widget is destroyed. Typically you call mainloop in the same scope that created the root window.
For example:
hi = GUI()
hi.root.mainloop()
If you don't like referencing the internal widget, give GUI a method like start or mainloop:
class GUI():
...
def start(self):
self.root.mainloop()
...
hi = GUI()
hi.start()
How can I get a blocking modal input dialog box in standard Python?
I need the user to input a value before the code can proceed.
Here is some not-working test code, but the idea is that I should be able to call MyDialog from anywhere in the script, so this is just a simplified example.
import tkinter
class MyDialog:
def __init__(self, prompt):
self.top = tkinter.Toplevel()
tkinter.Label(self.top, text=prompt).pack()
self.e = tkinter.Entry(self.top)
self.e.pack(padx=5)
tkinter.Button(self.top, text="OK", command=self.ok).pack(pady=5)
def ok(self):
self.top.destroy()
return self.e.get()
root = tkinter.Tk()
userName = MyDialog('Enter your name')
tkinter.Label(root, text="Hello {}".format(userName)).pack()
root.mainloop()
The dialog should not only disable the master window, but block whatever code called it. And it should be able to pass the value back to the calling code.
The solution requires two critical pieces. First, use grab_set to block all events in the other window (or, more correctly, send all events to the dialog window). Second, use wait_window to prevent the method from returning until the dialog has been destroyed.
That being said, you shouldn't be using it like in your example. You need to have the mainloop running before you create the window. It might work OK on some platforms, but in general you shouldn't expect your GUI to behave properly until mainloop is running.
Here's a simple example:
import Tkinter as tk
class MyDialog(object):
def __init__(self, parent, prompt):
self.toplevel = tk.Toplevel(parent)
self.var = tk.StringVar()
label = tk.Label(self.toplevel, text=prompt)
entry = tk.Entry(self.toplevel, width=40, textvariable=self.var)
button = tk.Button(self.toplevel, text="OK", command=self.toplevel.destroy)
label.pack(side="top", fill="x")
entry.pack(side="top", fill="x")
button.pack(side="bottom", anchor="e", padx=4, pady=4)
def show(self):
self.toplevel.grab_set()
self.toplevel.wait_window()
value = self.var.get()
return value
class Example(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.button = tk.Button(self, text="Click me!", command=self.on_click)
self.label = tk.Label(self, text="", width=40)
self.label.pack(side="top", fill="x")
self.button.pack(padx=20, pady=20)
def on_click(self):
result = MyDialog(self, "Enter your name:").show()
self.label.configure(text="your result: '%s'" % result)
if __name__ == "__main__":
root = tk.Tk()
Example(root).pack(fill="both", expand=True)
root.mainloop()