My variable is not changing and I know it's not changing because "1" is printed to the console.
I'm trying to make the label increment when i press the button. However when I press the button, the variable stays at 1.
What am I doing wrong?
I've looked online for an answer but I cannot really find one that I can understand.
num = 0
import tkinter
box = tkinter.Tk()
v = tkinter.StringVar()
labels = tkinter.Label(box, textvariable = v)
labels.pack()
def numberz(num,v):
num += 1
v.set(num)
print(num)
class MainWindow():
box.title("My Stupid Program")
buddon = tkinter.Button(box, text='PRESS ME', command = lambda:numberz(num,v))
buddon.pack()
box.mainloop()
num = 0
import tkinter
box = tkinter.Tk()
v = tkinter.StringVar()
labels = tkinter.Label(box, textvariable = v)
labels.pack()
def numberz(num,v):
num += 1
v.set(num)
print(num)
class MainWindow():
box.title("My Stupid Program")
buddon = tkinter.Button(box, text='PRESS ME', command = lambda:numberz(num,v))
buddon.pack()
box.mainloop()
You are changing the parameter num and not the global variable num
To change the global you need to specifically reference it. Notice how num is not passed in the lambda and now there is a global num in you function.
num = 0
import tkinter
box = tkinter.Tk()
v = tkinter.StringVar()
labels = tkinter.Label(box, textvariable = v)
labels.pack()
def numberz(v):
global num
num += 1
v.set(num)
print(num)
class MainWindow():
box.title("My Stupid Program")
buddon = tkinter.Button(box, text='PRESS ME', command = lambda:numberz(v))
buddon.pack()
box.mainloop()
In any case, using globals should be restricted to very specific cases and not be of general use.
Related
I have been trying to make a Python script that counts how many people are coming and going from your store.
How it is supposed to work:
you have a +1, and a -1 buttons;
when someone comes in, you click +1, and when someone goes away, you do -1.
What is wrong: when I click +1 it changes the counter from 0 to 1, but if I click it again, it doesn't change to 2.
The same thing happens when I do -1.
Here is the code:
import tkinter as tk
import customtkinter as ctk
app = ctk.CTk()
app.title('People Counter')
app.geometry('300x180')
ctk.set_appearance_mode("System")
ctk.set_default_color_theme("blue")
Label = ctk.CTkLabel
StringVar = ctk.StringVar
counter = 0
l1 = tk.Label(app, text=counter)
def pl1():
l1.config(text=counter + 1)
def mi1():
l1.config(text=counter - 1)
p1 = ctk.CTkButton(master=app,text = '+1', command=pl1, height=5 , width=30)
p1.place(relx=0.3, rely=0.5, anchor=tk.CENTER)
m1 = ctk.CTkButton(master=app, text="-1", command=mi1, height=5 , width=30)
m1.place(relx=0.7, rely=0.5, anchor=tk.CENTER)
l1.pack()
app.mainloop()
You only update the text on the label. You don't actually change the value of the counter variable. Try this:
def pl1():
global counter
counter += 1
l1.config(text=counter)
def mi1():
global counter
counter -= 1
l1.config(text=counter)
Another option is to create a simple Counter class with methods add() and sub(). It will help you avoid the use of global variables. I also added a test to prevent the counter get negative numbers.
import tkinter as tk
import customtkinter as ctk
app = ctk.CTk()
app.title('People Counter')
app.geometry('300x180')
ctk.set_appearance_mode("System")
ctk.set_default_color_theme("blue")
Label = ctk.CTkLabel
StringVar = ctk.StringVar
class Counter():
def __init__(self):
self.count = 0
def add(self):
self.count += 1
counter_display.config(text=self.count)
return self.count
def sub(self):
self.count -= 1
if self.count < 0:
self.count = 0
counter_display.config(text=self.count)
return self.count
def __repr__(self):
return str(self.count)
counter = Counter()
counter_display = tk.Label(app, text=counter)
add_one = ctk.CTkButton(
master=app,
text='+1',
command=counter.add,
height=5,
width=30
)
add_one.place(relx=0.3, rely=0.5, anchor=tk.CENTER)
sub_one = ctk.CTkButton(
master=app,
text='-1',
command=counter.sub,
height=5,
width=30
)
sub_one.place(relx=0.7, rely=0.5, anchor=tk.CENTER)
counter_display.pack()
app.mainloop()
The label in this application does not display the password once the generate button is clicked. I think it might be from the "for" loop. Any help would be appreciated.
from tkinter import *
from tkinter import ttk
import random
window = Tk()
window.resizable(False , False)
window.title('Password Generator')
window.geometry('400x200')
length = IntVar()
lbl = StringVar()
var1 = StringVar()
Alphabet = 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
showpass = ttk.Label(window , textvariable = lbl).pack()
def randalp():
for i in range(length):
random.choice(Alphabet)
ttk.Label(window , text = 'Password Lentgh:').pack()
numchoosen = ttk.Combobox(window, width = 12 , textvariable = length)
numchoosen['values'] = (5,6,7,8,9,10)
numchoosen.pack()
numchoosen.current(2)
numchoosen.config(state = 'readonly')
rad1 = ttk.Checkbutton(window , text = 'Alphabet' , variable = var1).pack()
def btnclick():
get1 = var1.get()
if rad1 == '1':
lbl.set(randalp)
print(lbl)
btn = ttk.Button(window , text = 'Generate' , command = btnclick).pack()
window.mainloop()
Does this fix it for You:
First You have to change Your randalp() function a bit:
def randalp():
string = list(Alphabet)
random.shuffle(string)
return string[:5]
I used shuffle because it just shuffles a list in a random order, so taking the first 5 items from that list would be random.
Also changed the btnclick() function:
def btnclick():
get1 = var1.get()
if get1 == '1':
lbl.set(randalp())
so now it uses the returned value of randalp()
Also You should fix a few formatting issues with Your code: suggestion: follow PEP 8 because it makes the code easier to read and don't use built-in function names (like len) as variable names; it is quite bad practice.
I'm learning to work with Python and Tkinter, so I'm doin this simple calculator app. My main problems come from the function calculator_tasks:
In the first condition, it should be deleting the 0, but it doesn't do it, why is that?
I'm trying to get text when I press the button, but it just prints '/', what's wrong in that?
Please see below the full code, so you might be able to help me.
from tkinter import *
import tkinter as tk
class calculator:
def __init__(self, master):
self.master = master
master.title("Calculator")
master.geometry("10x10")
grid_size = 4
a=0
while a <= grid_size:
master.grid_rowconfigure(a,weight=1, uniform='fred')
master.grid_columnconfigure(a,weight=1, uniform='fred')
a += 1
self.ini_frame = Frame(master,bg="light blue",highlightthickness=2, highlightbackground="black")
self.calc_title = Label(self.ini_frame, text ="Calculator",bg="light blue")
self.calculation_frame = Frame(master,bg="black")
self.calculation = IntVar(master,0)
self.calc_figure = Text(self.calculation_frame,fg="white",bg='black')
self.calc_figure.insert(END,0)
self.ini_frame.grid(columnspan=4,sticky=NSEW)
self.calculation_frame.grid(row=1,columnspan=4,sticky=NSEW)
self.calc_title.grid(padx=20)
self.calc_figure.grid(pady=20,padx=20)
master.update_idletasks()
def calculator_tasks():
if self.calc_figure.get("1.0",END) == 0:
self.calc_figure.delete(0,END)
self.calc_figure.insert(END,i)
else:
self.calc_figure.insert(END,i)
r = 2
c = 0
numbers = list(range(10))
numbers.remove(0)
self.calculator_btns=[ ]
for i in numbers:
if c == 2:
self.calculator_btns.append( Button(master, text = i, command = calculator_tasks))
self.calculator_btns[-1].grid(row = r, column = c, pady=20, padx=20,sticky=NSEW)
r += 1
c = 0
else:
self.calculator_btns.append( Button(master, text = i,command=calculator_tasks))
self.calculator_btns[-1].grid(row = r, column = c, pady=20, padx=20,sticky=NSEW)
c += 1
operators = ["+","*","/"]
self.operator_btns =[ ]
r=2
for i in operators:
self.operator_btns.append( Button(master, text = i))
self.operator_btns[-1].grid(row = r, column = 3, pady=20, padx=20,sticky=NSEW)
r += 1
root = Tk()
gui = calculator(root)
root.mainloop()
Here is a simple example:
According to your question: Retrieve text from button created in a loop
import tkinter as tk
root = tk.Tk()
####### Create Button ###############
def get_text(text):
print(text)
for i in range(10):
text = f'Hello I am BeginnerSQL74651 {i}'
button = tk.Button(root, text=text, command=lambda button_text=text: get_text(button_text))
button.grid()
root.mainloop()
This part of my program allows user to choose numbers from 1 to 5 and provide the sum of all numbers chosen. I want to disable the radio buttons when the sum reaches 30. How can I do that?
total_choices = [("1"),
("2"),
("3"),
("4"),
("5")]
var = tk.IntVar()
var.set(0)
sum = 0
def Calculator():
global sum
num = var.get()
sum = sum + num
if sum>30
# Grey out all the radio buttons
for val, choice in enumerate(total_choices):
tk.Radiobutton(root,
text=choice,
indicatoron = 0,
width = 10,
variable=var,
command=Calculator,
value=val).place(x=val*100,y=180)
You can disable radio buttons by looking them up from the children list of their parents:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def disable_multiple_radiobuttons():
global total
print(repr(sum_label['text']))
total += var.get()
sum_label['text'] = total
if total >= 30:
for child in root.winfo_children():
if child.winfo_class() == 'Radiobutton':
child['state'] = 'disabled'
root = tk.Tk()
var = tk.IntVar(value=1)
total = 0
sum_label = tk.Label(root, text=total)
sum_label.pack()
for i in range(1, 6):
tk.Radiobutton(root, text=i, variable=var, value=i,
command=disable_multiple_radiobuttons).pack()
tk.mainloop()
or you can put them in a collection type and simply disable them at ease:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
def on_rb_press():
sum_label['text'] += var.get()
if sum_label['text'] >= 30:
for key in radiobuttons:
radiobuttons[key]['state'] = 'disabled'
root = tk.Tk()
sum_label = tk.Label(root, text=0)
sum_label.pack()
radiobuttons = dict()
var = tk.IntVar(value=1)
for i in range(1, 6):
radiobuttons[i] = tk.Radiobutton(root, text=i, variable=var,
value=i, command=on_rb_press)
radiobuttons[i].pack()
tk.mainloop()
I would store all the radio buttons in a list, then disable every buttons when you reach 30, as seen below :
total_choices = [("1"),
("2"),
("3"),
("4"),
("5")]
var = tk.IntVar()
var.set(0)
sum = 0
def Calculator():
global sum
global buttons
num = var.get()
sum = sum + num
if sum>30
# Grey out all the radio buttons
for b in buttons:
b.config(state=disabled)
global buttons
buttons = list()
for val, choice in enumerate(total_choices):
buttons.append(tk.Radiobutton(root,
text=choice,
indicatoron = 0,
width = 10,
variable=var,
command=Calculator,
value=val))
buttons[-1].place(x=val*100,y=180))
from Tkinter import *
window = Tk()
frame=Frame(window)
frame.pack()
text_area = Text(frame)
text_area.pack()
text1 = text_area.get('0.0',END)
def cipher(data):
As,Ts,Cs,Gs, = 0,0,0,0
for x in data:
if 'A' == x:
As+=1
elif x == 'T':
Ts+=1
elif x =='C':
Cs+=1
elif x == 'G':
Gs+=1
result = StringVar()
result.set('Num As: '+str(As)+' Num of Ts: '+str(Ts)+' Num Cs: '+str(Cs)+' Num Gs: '+str(Gs))
label=Label(window,textvariable=result)
label.pack()
button=Button(window,text="Count", command= cipher(text1))
button.pack()
window.mainloop()
What I'm trying to accomplish is entering a string of 'AAAATTTCA' in my Text widget and have the label return the number of occurrences. With the entry 'ATC' the function would return Num As: 1 Num Ts: 1 Num Cs: 1 Num Gs: 0.
What I don't understand is why I am not reading in my text_area correctly.
I think you misunderstand some concepts of Python an Tkinter.
When you create the Button, command should be a reference to a function, i.e. the function name without the (). Actually, you call the cipher function once, at the creation of the button. You cannot pass arguments to that function. You need to use global variables (or better, to encapsulate this into a class).
When you want to modify the Label, you only need to set the StringVar. Actually, your code creates a new label each time cipher is called.
See code below for a working example:
from Tkinter import *
def cipher():
data = text_area.get("1.0",END)
As,Ts,Cs,Gs, = 0,0,0,0
for x in data:
if 'A' == x:
As+=1
elif x == 'T':
Ts+=1
elif x =='C':
Cs+=1
elif x == 'G':
Gs+=1
result.set('Num As: '+str(As)+' Num of Ts: '+str(Ts)+' Num Cs: '+str(Cs)+' Num Gs: '+str(Gs))
window = Tk()
frame=Frame(window)
frame.pack()
text_area = Text(frame)
text_area.pack()
result = StringVar()
result.set('Num As: 0 Num of Ts: 0 Num Cs: 0 Num Gs: 0')
label=Label(window,textvariable=result)
label.pack()
button=Button(window,text="Count", command=cipher)
button.pack()
window.mainloop()