Can someone help me with parameters in tkinter "command" [duplicate] - python

This question already has an answer here:
Tkinter assign button command in a for loop with lambda [duplicate]
(1 answer)
Closed 1 year ago.
I'm trying to make a little file explorer with just buttons, I'm still in the early stages and want to make a function prints which button was pressed and came up with this:
import tkinter as tk
buttons = []
window = tk.Tk()
window.geometry("200x100")
def open(button):
print(button)
def list(titles):
i=0
while i<(len(titles)):
btn = tk.Button(text=titles[i], width=20, command=lambda: open(i))
buttons.append(btn)
buttons[i].grid(row=i, column=1)
print(f"adding {titles[i]}")
i=i+1
list(["title1", "title2", "title3"])
window.mainloop()
There's one problem: It always prints 3. I think I know what the problem is, i always stays 3 after generating the button so it passes 3 to the function, but I don't know how to solve it.
I used the lambda cuz I cant pass parameters just using open(i) and found the lambda-solution to that on this question .
Can someone help?
Tnx!

Because it over writes the commands on one button when you assign it again. Do:
import tkinter as tk
buttons = []
window = tk.Tk()
window.geometry("200x100")
def open(button):
print(button)
def list(titles):
btn = tk.Button(text=titles[0], width=20, command=lambda: open(1))
buttons.append(btn)
buttons[0].grid(row=1, column=1)
print(f"adding {titles[0]}")
btn = tk.Button(text=titles[1], width=20, command=lambda: open(2))
buttons.append(btn)
buttons[1].grid(row=2, column=1)
print(f"adding {titles[1]}")
btn = tk.Button(text=titles[2], width=20, command=lambda: open(2))
buttons.append(btn)
buttons[2].grid(row=3, column=1)
print(f"adding {titles[2]}")
list(["title1", "title2", "title3"])
window.mainloop()

Related

Tkinter SyntaxError: keyword argument repeated: state (how to make a button one time clickable?)

from tkinter import *
def Click():
label = Label(root, text="You clicked it")
label.pack()
root = Tk()
label2 = Label(root, text="You can only click one time")
Button = Button(root, text="Click me", padx=20, pady=20, state=NORMAL,
command=Click,state=DISABLED)
Button.pack()
label2.pack()
root.mainloop()
Because I use state 2 times I am getting this error:
SyntaxError: keyword argument repeated: state
How can I fix this error and make a button that can be clicked one time?
This should do what you want. The idea is to update the button's state from within the click handler function.
FYI, star imports can cause trouble and are best avoided, so I've done that here. I've also changed some variable names to use lowercase, since capitalized names are typically reserved for class objects in Python (things like Label and Tk, for instance!)
import tkinter as tk
def click():
label = tk.Label(root, text="You clicked it")
label.pack()
button.config(state=tk.DISABLED) # disable the button here
root = tk.Tk()
label2 = tk.Label(root, text="You can only click one time")
button = tk.Button(root, text="Click me", padx=20, pady=20, command=click)
button.pack()
label2.pack()
root.mainloop()
Bonus Round - if you want to update the existing label (label2, that is) instead of creating a new label, you can also accomplish this with config
def click():
label2.config(text="You clicked it") # update the existing label
button.config(state=tk.DISABLED) # disable the button here

How can I make windows show up one at a time in python tkinter?

How can I make windows show up one at a time with tkinter? For example, if I typed in 6 as an input, and called a function with a button, I need it to show me 6 windows, but one at a time. It will only prompt me the next window after pressing a button from the previous one.
I tried using a for loop to loop through the range of the input, and create new windows with a button based on that range, but the problem is that they all show up at the same time:
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.title("Multiple windows")
def multiplewindows():
for i in range(int(number.get())):
tempwindow = Toplevel()
tempwindow.title(f"Window {i+1}")
tempbutton = Button(tempwindow, text=f"Button {i+1}")
tempbutton.pack(padx=10, pady=10)
number = Entry(root, width=5)
number.pack(padx=10, pady=10)
button = Button(root, text="Show", command=multiplewindows)
button.pack(padx=10, pady=10)
root.mainloop()
Is there any way to pause the for loop and allow it to continue after pressing the button in the newly created window?
I think you don't need for loop to do this
def multiplewindows():
j=int(number.get())
tempwindow = Toplevel()
tempwindow.title(f"Window {j}")
tempbutton = Button(tempwindow, text=f"Button {j}")
tempbutton.pack(padx=10, pady=10)
And if you want to use for loop to do this
def multiplewindows():
j=int(number.get())
for i in range(int(number.get())):
if (i+1)==j:
tempwindow = Toplevel()
tempwindow.title(f"Window {j}")
tempbutton = Button(tempwindow, text=f"Button {j}")
tempbutton.pack(padx=10, pady=10)
The easiest way to do this is like acw1668 was recommanded with the builtin method of tkinter that is calld with wait_window().
from tkinter import *
from tkinter.ttk import *
root = Tk()
root.title("Multiple windows")
def multiplewindows():
for i in range(int(number.get())):
tempwindow = Toplevel()
tempwindow.title(f"Window {i+1}")
tempbutton = Button(tempwindow, text=f"Button {i+1}", command=tempwindow.destroy)
tempbutton.pack(padx=10, pady=10)
tempwindow.wait_window()
number = Entry(root, width=5)
number.pack(padx=10, pady=10)
button = Button(root, text="Show", command=multiplewindows)
button.pack(padx=10, pady=10)
root.mainloop()
Here we have created a function with a forloop that waits until the window is destroyed and added a command to the Button to destroy the window.

How to use GUI Tkinter button to increment a number and display it

I'm new to trying out python GUI's and tried tkinter and pyglet, but only through tutorials, in-order-to understand the basic classes and functions. But what I'm currently trying to do is to get a button to increase a number whilst displaying that number at the same time. Somehow, even though the variable number was stated globally as 0, the function to increase it doesn't do anything, it actually produces an error: 'UnboundLocalError: local variable 'number' referenced before assignment'. I have no idea how to correct this.
The tutorials I've seen on both YouTube and as an article, don't talk about how to do this exactly. The article does mention how to change a certain text though, but not a previously created variable (which in my case would be 'number').
from tkinter import *
number = 0
window = Tk()
window.title("Programme")
window.geometry('350x250')
label = Label(window, text=number)
label.grid(column=0,row=0)
def clicked():
number += 1
button = Button(window, text="Push Me", command=clicked)
button.grid(column=1, row=2)
window.mainloop()
Is there any way to do this?
Also I've been looking for how to add time, to handle events and such, through ticks. But everything I find on the internet is about literally displaying a clock on the GUI, which is useless, or at least I don't know how to use it to have a ticking function.
You need to increment the number, like you do, but also update the Label to display the new number:
from tkinter import *
number = 0
window = Tk()
window.title("Programme")
window.geometry('350x250')
label = Label(window, text=number)
label.grid(column=0,row=0)
def clicked():
global number
number += 1
label.config(text=number)
button = Button(window, text="Push Me", command=clicked)
button.grid(column=1, row=2)
window.mainloop()
An easier way to do this is to use tkinter's version of an integer: IntVar. It takes care of the Label updates automatically, but it requires you use get() and set() to work with it.
from tkinter import *
def clicked():
number.set(number.get()+1)
window = Tk()
window.title("Programme")
window.geometry('350x250')
number = IntVar()
label = Label(window, textvariable=number)
label.grid(column=0,row=0)
button = Button(window, text="Push Me", command=clicked)
button.grid(column=1, row=2)
window.mainloop()
Here is my entire code:
from tkinter import *
def up():
number.set(number.get()+1)
def down():
number.set(number.get()-1)
window = Tk()
window.title("Programme")
window.geometry('350x250')
number = IntVar()
frame = Frame(window)
frame.pack()
entry = Entry(frame, textvariable=number, justify='center')
entry.pack(side=LEFT, ipadx=15)
buttonframe = Frame(entry)
buttonframe.pack(side=RIGHT)
buttonup = Button(buttonframe, text="▲", font="none 5", command=up)
buttonup.pack(side=TOP)
buttondown = Button(buttonframe, text="▼", font="none 5", command=down)
buttondown.pack(side=BOTTOM)
window.mainloop()
It looks better for me when the buttons are inside of the entry widget directly.

Tkinter with Python [duplicate]

This question already has an answer here:
How do I create child windows with Python tkinter?
(1 answer)
Closed 5 years ago.
I am quite new to Python and started learning Tkinter yesterday. I am creating a banking system and I have a Menu made out of the buttons. The problem that I have is that I do not know how to open an additional window when the button is clicked. I have tried with top=Toplevel(), but it only opens two windows on top of each other. What I need is for the additional window to open only when it is activated with a button(event). Can someone help me because I am really stuck as I have about six buttons?
My code so far is:
root.minsize(width=400, height=400)
root.maxsize(width=400, height=400)
root.configure(background='#666666')
label = Frame(root).pack()
Lb = Label(label, text='Welcome to Main Menu',bg='#e6e6e6', width=400).pack()
menu = Frame(root,).pack()
btn_1 = Button(menu, text='Make Deposit', width=15, height=2).pack(pady=5)
btn_2 = Button(menu, text='Withdrawal', width=15, height=2).pack(pady=5)
btn_3 = Button(menu, text='Accounts', width=15, height=2).pack(pady=5)
btn_4 = Button(menu, text='Balance', width=15 ,height=2).pack(pady=5)
btn_5 = Button(menu, text='Exit', width=15, height=2).pack(pady=5)
root.mainloop()
Thank you for the help in advance
Maybe this could work:
from Tkinter import *
class firstwindow:
def __init__(self):
#Variables
self.root= Tk()
self.switchbool=False
#Widgets
self.b = Button(self.root,text="goto second window",command= self.switch)
self.b.grid()
self.b2 = Button(self.root,text="close",command= self.root.quit)
self.b2.grid()
self.root.mainloop()
#Function to chage window
def switch(self):
self.switchbool=True
self.root.quit()
self.root.destroy()
class secondwindow:
def __init__(self):
self.root= Tk()
self.b2 = Button(self.root,text="close",command= self.root.quit)
self.b2.grid()
self.root.mainloop()
one = firstwindow()
if one.switchbool:
two = secondwindow()
Take a look to the Tkinter reference. Check all universal methods and widgets methods. You can do anything you want.
Below is a small example of how you can open a window by clicking on a button. When the user clicks on the button, the function open_window, which was passed to the command option of the button, is called.
import tkinter as tk
def open_window():
top = tk.Toplevel(root)
tk.Button(top, text='Quit', command=top.destroy).pack(side='bottom')
top.geometry('200x200')
root = tk.Tk()
tk.Button(root, text='Open', command=open_window).pack()
tk.Button(root, text='Quit', command=root.destroy).pack()
root.mainloop()

Python 3 Tkinter appending label to print user input from entry label

Hey guys I have just started learning about GUI's and in particular just started using tkinter. I have spent hours searching forums for what I believe should be an obvious and simple solution and found a few people asking similar questions but i failed to understand the solutions.
Basically I am just trying to get the user to input a letter with an entry widget and display that on a label when the go button is pressed. If anyone could explain to me how to do this I would be extremely grateful.
Here's the code I have written:
#!/usr/bin/env python3
from tkinter import*
from tkinter import ttk
import random
root = Tk()
root.title('test')
frame = ttk.Frame(root, padding='3 3 12 12 ')
frame.grid(column=0, row=0, sticky=(N, W, E, S))
frame.columnconfigure(0, weight=1)
frame.rowconfigure(0, weight=1)
letter = StringVar()
def gobutton(*args):
print_label['text'] += letter
print_label = ttk.Label(frame, text="")
print_label.grid(column=1, row=1, sticky=N)
letter_entry = ttk.Entry(frame, width=7, textvariable=letter)
letter_entry.grid(column=1, row=2, sticky=S)
g_button = ttk.Button(frame, width=7, text='GO', command=gobutton)
g_button.grid(column=3, row=3, sticky=S)
for child in frame.winfo_children():
child.grid_configure(padx=5, pady=5)
letter_entry.focus() #WHAT DOES THIS DO?
root.bind('<Return>', gobutton)
root.mainloop()
You should .get() what StringVar contains when button is clicked.
def gobutton(): #if you don't plan to pass any parameters, *args is unnecesarry
print_label['text'] += letter.get()
Also, for this program, using a StringVar a little bit overkill. You can easily go for Entry.get() to get what entry contains. Below code demonstrates how to use get() method with a quite simple(and a little bit dirty) code.
def getMethod():
lbl.configure(text=ent.get())
#or
#lbl["text"] = ent.get()
root = tk.Tk()
tk.Button(root, text="Get Entry", command=getMethod).pack()
ent = tk.Entry(root)
lbl = tk.Label(root, text = "Before click")
lbl.pack()
ent.pack()
root.mainloop()
.focus() is an alias for .focus_set() method.
Moves the keyboard focus to this widget. This means that all keyboard
events sent to the application will be routed to this widget.

Categories

Resources