Binding 'Return' press to Button in Python - python

I am trying to get the Return/Enter key to do the same thing as the 'Enter' button in my program. I have looked at other answers on StackOverflow but none of them solved my problem.
from tkinter import *
from tkinter import messagebox
import random
class Application(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.grid()
self.create_widgets()
self.number = random.randrange(10)
def create_widgets(self):
self.guess_lbl = Label(self, text = "Enter a Guess:")
self.guess_lbl.grid(row = 2, column = 0, sticky = W)
self.guess_ent = Entry(self, width = 10)
self.guess_ent.grid(row = 2, column = 1, sticky = W)
self.submit_bttn = Button(self, text = "Enter", command = self.reveal)
self.submit_bttn.grid(row = 6, column = 0, sticky = W)
self.submit_bttn.bind('<Return>', self.reveal)
def reveal(self):
guess = self.guess_ent.get()
if int(guess) == int(self.number):
messagebox.showinfo("Guessing game ", "Good Guess, that is correct!")
# Main
root = Tk()
root.title("Guessing Game")
root.geometry("300x100")
app = Application(root)
root.mainloop()

You need to add this to your def __init__(self, master) function:
master.bind('<Return>', self.reveal)
And you need to update your def reveal(self): method to:
def reveal(self, event=None):
Finally you need to remove the last line under your def create_widgets(self): method.
self.submit_bttn.bind('<Return>', self.reveal) # delete this
Afterwards, you will be able to press your Enter key on your keyboard and it should work for you.

Related

Tkinter Python: Grid &Entry problem. How to add and remove dynamicly Entry&delete Button wingets

Hi im trying to write simple app with posibility to add and delete Entry boxes and i cant get the expected result.
What i want : add button add a row with entry and delete this entry button
what i get :Entry is not created and delete button is not his column
here is my code:
from tkinter import *
class App():
def __init__(self, root):
self.root=root
self.all_entries = []
self.addboxButton = Button(root, text='<Add >', command=self.addBox)
self.addboxButton.grid(row=0, column=0)
self.rows =[]
def addBox(self):
print ("ADD")
new_row = Row(self,root)
self.rows.append(new_row)
self.render()
def render(self):
for i in range(len(self.rows)):
self.rows[i].grid(row=i + 1, column=1, sticky=W,columnspan=2, padx=(5, 0), pady=(5, 0))
class Row(Frame):
def __init__(self,parent, main_frame, **kwargs):
super(Row, self).__init__()
self.main_frame = main_frame
self.entryRowVar = StringVar()
self.entryRow= Entry(self.main_frame, textvariable=self.entryRowVar)
self.entryRow.grid(row=0, column=1, sticky=W,)
self.del_btn = Button(self, text='Delete')
self.del_btn.grid(row=0, column=2, sticky=W,)
if __name__ == "__main__":
root = Tk()
app = App(root)
root.mainloop()

Tkinter: How to pass arguments from Entry widgets to function?

I have created two Entry widgets called name_entry and passwd_entry. After the user enters his name and password, the program should subsequently list it if the user clicks on the Submit button.
Unfortunately this is not working. I'm trying to write it within a class and to pass it as an argument to my submit function.
I receive this error:
File "/usr/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
TypeError: submit() missing 2 required positional arguments: 'var_name' and 'var_passwd'
Code:
#/usr/bin/python3.7
from tkinter import *
class Window (Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("GUI")
self.pack(fill=BOTH, expand=1)
var_name = StringVar()
var_passwd = StringVar()
name = Label(self, text="Name: ")
name.place(x = 0, y = 0)
name_entry = Entry(root, textvariable = var_name)
name_entry.place(x = 90, y =0)
passwd = Label(self, text="Password: ")
passwd.place(x = 0, y = 90)
passwd_entry = Entry(root, textvariable = var_passwd)
passwd_entry.place(x = 90, y = 90)
Knop1 = Button(self, text="Submit", command=self.submit)
Knop1.place(x = 180, y=180)
def submit (self, var_name, var_passwd):
naam = var_name.get()
var_passwd = var_passwd.get()
print("The name is: ", naam)
print("The password is: ", var_passwd)
root = Tk()
root.geometry("500x300")
app = Window(root)
app.mainloop()
Can anyone help me? I'm also looking for a good Tkinter tutorial where OOP is being used.
You haven't passed the variables to the submit function button. For simple cases like this, you can use a lambda expression as a link between Tkinter and the callback function, otherwise Python will call the callback function before creating the widget: https://effbot.org/zone/tkinter-callbacks.htm
from tkinter import *
class Window (Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("GUI")
self.pack(fill=BOTH, expand=1)
var_name = StringVar()
var_passwd = StringVar()
name = Label(self, text="Name: ")
name.place(x = 0, y = 0)
name_entry = Entry(root, textvariable = var_name)
name_entry.place(x = 90, y =0)
passwd = Label(self, text="Password: ")
passwd.place(x = 0, y = 90)
passwd_entry = Entry(root, textvariable =var_passwd)
passwd_entry.place(x = 90, y = 90)
# Changed this line
Knop1 = Button(self, text="Submit", command=lambda: self.submit(var_name, var_passwd))
Knop1.place(x = 180, y=180)
def submit (self, var_name, var_passwd):
naam = var_name.get()
var_passwd = var_passwd.get()
print("The name is: ", naam)
print("The password is: ", var_passwd)
root = Tk()
root.geometry("500x300")
app = Window(root)
app.mainloop()
To address your question about OOP with tkinter, this question has some good advice: Best way to structure a tkinter application?
As a general rule it's best of the command of a button calls a function that accepts no arguments. Since you've made a special-purpose function that always operates on the same variables, you can have the directly access the variables.
First, make the variables an attribute of the class:
def init_window(self):
...
self.var_name = StringVar()
self.var_passwd = StringVar()
..
Then, define your function to access those variables:
def submit (self):
naam = self.var_name.get()
var_passwd = self.var_passwd.get()
...
And finally, modify how your button calls this function:
Knop1 = Button(self, text="Submit", command=self.submit)
Note: if you're not using the special properties of a tkinter variable (such as the trace mechanism), you don't need to use StringVar at all.
Example:
def init_window(self):
...
self.name_entry = Entry(root, textvariable = var_name)
self.passwd_entry = Entry(root, textvariable =var_passwd)
...
def submit (self):
naam = self.name_entry.get()
var_passwd = self.passwd_entry.get()
...

Python Tkinter - processing data entered by a user

I want to create a program in Python with Tkinter GUI, and I want it to take string inputs from a user, then I want to do some operations on these strings - in this case, I want to mix parts of two words and get a new word. How can I handle this data entered by a user and use it to receive the result? Below is my code. I couldn't find the answer to this problem and nothing I tried works.
from Tkinter import *
class Window(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title("Mix words")
self.pack(fill=BOTH, expand=1)
menu = Menu(self.master)
self.master.config(menu=menu)
entryLbl1 = Label(self, text="Write the first word: ")
entryLbl1.pack()
self.entrytext1 = StringVar()
Entry(self, textvariable=self.entrytext1).pack()
self.buttontext1 = StringVar()
self.buttontext1.set("OK")
Button(self, textvariable=self.buttontext1, command=self.clicked1).pack()
self.label1 = Label(self, text="")
self.label1.pack()
global user_entry1
user_entry1 = self.entrytext1.get()
entryLbl2 = Label(self, text="Write the second word: ")
entryLbl2.pack()
self.entrytext2 = StringVar()
Entry(self, textvariable=self.entrytext2).pack()
self.buttontext2 = StringVar()
self.buttontext2.set("OK")
Button(self, textvariable=self.buttontext2, command=self.clicked2).pack()
self.label2 = Label(self, text="")
self.label2.pack()
global user_entry2
user_entry2 = self.entrytext2.get()
entryLbl3 = Label(self, text="Result: ")
entryLbl3.pack()
self.buttontext3 = StringVar()
self.buttontext3.set("Result")
Button(self, textvariable=self.buttontext1, command=self.clicked3).pack()
self.label3 = Label(self, text="")
self.label3.pack()
def clicked1(self):
input = self.entrytext1.get()
self.label1.configure(text=input)
def clicked2(self):
input = self.entrytext2.get()
self.label2.configure(text=input)
def clicked3(self):
self.user_entry1 = user_entry1
self.user_entry2 = user_entry2
first2a = user_entry1[0:2]
rest_a = user_entry1[2:]
first2b = user_entry2[0:2]
rest_b = user_entry2[2:]
input = first2b + rest_a + " " + first2a + rest_b
self.label3.configure(text=input)
root = Tk()
root.iconbitmap("py.ico")
root.geometry("600x300")
app = Window(root)
root.mainloop()
You need Entry() objects.
The following will show two Entry widgets and a Button.
When the button is pressed, the contents of both of the Entry objects will be printed to the console:
import sys
# Determine if you're running Python 3
is_py_3 = sys.version[0] == '3'
# Import Tkinter for the correct version of Python
if is_py_3:
from tkinter import Button, Entry, Tk
else:
from Tkinter import Button, Entry, Tk
class GUI:
def __init__(self):
# Set up the "Root" or "Parent" of the window.
self.root = Tk()
# Set up two "Entry" widgets.
self.entry1 = Entry(self.root)
self.entry1.insert(0, "Enter something here.")
self.entry2 = Entry(self.root)
self.entry2.insert(0, "and here...")
# Set up a button to handle the event.
self.button = Button(self.root, text="CLICK ME", command=self.onClicked)
self.entry1.pack()
self.entry2.pack()
self.button.pack()
def onClicked(self):
# Print the contents of the entry widgets.
s1 = self.entry1.get()
s2 = self.entry2.get()
print(s1, s2)
app = GUI()
app.root.mainloop()

Tkinter does not show one frame

I am trying to make a GUI for my program but I have changed my code a lot and I saw that GUI misses one frame but it was fine before.
Could anyone help me and tell why a frame with a button does not appear on the bottom?
Whole "button_part" object does not appear.
from tkinter import *
import tkinter as tk
import os
import glob
BOUNDS = ["Last week", "Last 2 weeks", "Last 3 weeks"]
class settings_part:
path_to_copy = 0
def __init__(self, master, update_func):
path_to_copy = StringVar()
settings_frame = Frame(master, background="")
settings_frame.pack(side=TOP, fill=X)
date_bound = StringVar()
date_bound.set(BOUNDS[1])
date_option = OptionMenu(settings_frame, date_bound, *BOUNDS, command=update_func)
date_option.config(background="#732c30")
date_option.config(foreground="white")
date_option.config(bd=0)
date_option.pack(side=LEFT, padx=5, pady=5)
path_to_copy.set("~/Python/usun")
box_with_path = Entry(settings_frame, textvariable=path_to_copy)
box_with_path.pack(side=RIGHT, padx=5, pady=5)
# s = path_to_copy.get()
class songs_part:
def __init__(self, master, root):
self.songs_frame = Frame(master)
self.update_songs(root.list_of_songs)
self.songs_frame.pack()
def update_songs(self, l):
for song in l:
c = Checkbutton(self.songs_frame, text=song[0], variable=song[1])
c.pack()
class button_part:
def __init__(self, master, copyFunc):
self.button_frame = Frame(master)
btn_image = PhotoImage(file="copybtn.png")
self.copy_button = Button(self.button_frame, command=copyFunc, text="Copy",
image=btn_image, highlightthickness=0, bd=0, activebackground="#732c30")
self.copy_button.pack()
class App:
def __init__(self):
root = Tk()
root.title("Copying songs")
root.geometry("500x500")
root.option_add("*Font", "Calibra")
back_image = PhotoImage(file="back.png")
self.window = Label(root, image=back_image)
self.window.pack(fill="both", expand="yes")
self.list_of_songs = list()
self.make_list_of_songs()
self.set_part = settings_part(self.window, self.update_list)
self.son_part = songs_part(self.window, self)
self.but_part = button_part(self.window, self.copy_songs)
root.mainloop()
def make_list_of_songs(self):
owd = os.getcwd()
os.chdir("/home/stanek/Music/usun")
for file in glob.glob("*.mp3"):
self.list_of_songs.append([file, tk.IntVar()])
os.chdir(owd)
def copy_songs(self):
for s in self.list_of_songs:
print(s)
def update_list(self, arg):
print("updating list with songs from " + arg)
self.son_part = songs_part(self.window, self)
if __name__ == '__main__':
App()
You never pack the button frame.

Create n number of windows in tkinter

I am writing a programm in which I am trying to open a n number of windows. My code is:
from tkinter import *
from tkinter import ttk
class Main_window(ttk.Frame):
"""A program"""
def __init__(self, master):
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
"""Creates all the objects in the window"""
self.min_lbl = ttk.Label(self, text = "1").grid(row = 0, column = 0,
sticky = W)
self.max_lbl = ttk.Label(self, text = "100").grid(row = 0, column = 2,
sticky = W)
spinval = IntVar()
self.scale = ttk.Scale(self, orient = HORIZONTAL,
length = 200,
from_ = 1, to = 100,
variable = spinval,
command=self.accept_whole_number_only)
self.scale.grid(row = 0,column = 1,sticky = W)
self.spinbox = Spinbox(self, from_ = 1, to = 100,
textvariable = spinval,
command = self.update,
width = 10)
self.spinbox.grid(row = 0,column =3,sticky = W)
self.go_bttn = ttk.Button(self, text = "Go",
command = self.create_windows
).grid(row = 1, column = 1, sticky = W)
def accept_whole_number_only(self, e=None):
"""Makes the numbers from the scale whole"""
value = self.scale.get()
if int(value) != value:
self.scale.set(round(value))
def update(self):
"""Updates the scale and spinbox"""
self.scale.set(self.spinbox.get())
def create_windows(self):
"""This function will create all the new windows"""
value = self.scale.get()
window_num = value
negative_window_num = 1
while window_num != 0:
root = Tk()
root.title("This is Window "+str(window_num)[:-2]+" of "+str(value)[:-2])
root.geometry("350x200")
app = Window_creator(root)
root.mainloop()
window_num -= 1
class Window_creator(ttk.Frame):
"""makes child windows"""
def __init__(self, master):
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
"""creates all the widgets in the window"""
def main():
"""Loops the window"""
root = Tk()
root.title("Programm")
root.geometry("350x200")
app = Main_window(root)
root.mainloop()
main()
What I want this code to do is I want to be able to set the spinbox or scale to number n and then when I click the Button i want n numbers of child windows to appear. I tried this with a while loop but it doesn't quite work like I want it to by creating a new window just after the I closed the prevoius window. You also have to close the main window first for it to work (I am going to make the button close the window automatically later). Any Ideas on how I could make this work?
Call child = Toplevel(), instead of root = Tk().
Also, you can not call mainloop more than once (since there should be only one event loop).
from tkinter import *
from tkinter import ttk
class Main_window(ttk.Frame):
"""A program"""
def __init__(self, master):
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
"""Creates all the objects in the window"""
self.min_lbl = ttk.Label(self, text = "1").grid(row = 0, column = 0,
sticky = W)
self.max_lbl = ttk.Label(self, text = "100").grid(row = 0, column = 2,
sticky = W)
spinval = IntVar()
self.scale = ttk.Scale(self, orient = HORIZONTAL,
length = 200,
from_ = 1, to = 100,
variable = spinval,
command=self.accept_whole_number_only)
self.scale.grid(row = 0,column = 1,sticky = W)
self.spinbox = Spinbox(self, from_ = 1, to = 100,
textvariable = spinval,
command = self.update,
width = 10)
self.spinbox.grid(row = 0,column =3,sticky = W)
self.go_bttn = ttk.Button(self, text = "Go",
command = self.create_windows
).grid(row = 1, column = 1, sticky = W)
def accept_whole_number_only(self, e=None):
"""Makes the numbers from the scale whole"""
value = self.scale.get()
if int(value) != value:
self.scale.set(round(value))
def update(self):
"""Updates the scale and spinbox"""
self.scale.set(self.spinbox.get())
def create_windows(self):
"""This function will create all the new windows"""
value = self.scale.get()
window_num = value
negative_window_num = 1
for n in range(int(window_num)):
child = Toplevel()
child.title("This is Window "+str(window_num)[:-2]+" of "+str(value)[:-2])
child.geometry("350x200")
app = Window_creator(child)
class Window_creator(ttk.Frame):
"""makes child windows"""
def __init__(self, master):
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
"""creates all the widgets in the window"""
def main():
"""Loops the window"""
root = Tk()
root.title("Programm")
root.geometry("350x200")
app = Main_window(root)
root.mainloop()
main()

Categories