why label doesnt work?Is it for 'for' loop? - python

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.

Related

Why is this not working? tkinter label should change text on button click

Why is this not working? On button click it should add 1.
from tkinter import *
root = Tk()
m = 0
def clicka(m):
m = m + 1
lbl = Label(text=str(m)).place(relx=0.1, rely = 0.2)
exe = Button(text = '↵', bg = 'black', fg = 'red',command=clicka(m), relief='flat').place(relx=0.19, rely = 0.32)
lbl = Label(text=str(m)).place(relx=0.1, rely = 0.2)
root.mainloop()
There are issues in your code:
command=clicka(m) will execute clicka(m) immediately and assign the result of clicka(m) (which is None) to command option. So nothing will be done when the button is clicked later.
passing variable of primitive type will be passed by value, so even it is modified inside the function, the original variable will not be updated.
I would suggest to change m to IntVar and associate it to lbl via textvariable option, then updating m will update lbl at once:
import tkinter as tk
root = tk.Tk()
def clicka():
m.set(m.get()+1)
tk.Button(text='↵', bg='black', fg='red', command=clicka, relief='flat').place(relx=0.19, rely = 0.32)
m = tk.IntVar(value=0)
tk.Label(textvariable=m).place(relx=0.1, rely = 0.2)
root.mainloop()
You could try to set the variable m as global
from tkinter import *
root = Tk()
m = 0
def clicka():
global m
m = m + 1
lbl = Label(text=str(m)).place(relx=0.1, rely = 0.2)
print('Hi')
exe = Button(text = '↵', bg = 'black', fg = 'red',command=clicka, relief='flat').place(relx=0.19, rely = 0.32)
lbl = Label(text=str(m)).place(relx=0.1, rely = 0.2)
root.mainloop()
Indeed like #acw1668 mentioned, you can work with lambda or you can just use global.
This is much shorter.
from tkinter import *
root = Tk()
m = 0
def clicka():
global m
m += 1
lbl["text"] = str(m)
exe = Button(text='↵', bg='black', fg='red', command=clicka, relief='flat')
exe.place(relx=0.19, rely=0.32)
lbl = Label(text=str(m))
lbl.place(relx=0.1, rely=0.2)
root.mainloop()
You could try this :
from tkinter import *
win = Tk()
myvar = IntVar()
def Adder():
k = int(myvar.get())
k = k + 1
lb.insert(1 , k)
win.geometry("750x750")
l1 = Label(win , text = "Number")
l1.grid(row = 0 , column = 0)
e1 = Entry(win , textvariable = myvar)
e1.grid(row = 1 , column = 0)
b = Button(win , command = Adder)
b.grid(row = 2 , column = 0)
lb = Listbox(win , width = 20)
lb.grid(row = 3 , column = 0)
win.mainloop()
well this is the real code!!!
first of all , this question is just about add one number to 1 ;
so our function (you could use lambda function too) could place in the main statements but , how it's work ? in tkinter module , the variables must be define with the Reserved words like StringVar and IntVar. second if you wondering why i put
lb.insert(1,k)
in the function and how it works ? i have to say this "lb" variable, is a global variable in all part of the program, from the beginning to the end, and the Adder function can use it too , besides if you put (lb) variable beneath the
lb.grid(row =3 , column = 0)
lb.insert(1 , Adder())
Adder just calculate the amount of variable but insert method can't show the result (insert method doesn't have this).
I hope it was helpful.

Why exec function in python adds '.!' at the beginning of the text?

I am currently working on a hangman game using tkinter in python.
When I click a button of the letter and it is in the word that we are guessing it should show the letter. But when I click the button this problem is popping up:
This example is only with one button. People say that this problem is because of the mainloop(), but i have no idea how to fix it.
from tkinter import *
from tkinter import messagebox
from generate_word import word
#DEFAULT VALUES
score = 0
count = 0
win_count = 2
WINDOW_BG = '#e5404e'
WINDOW_SIZE = '1200x870+300+80'
FONT = ('Arial', 40)
from tkinter import *
from tkinter import messagebox
from generate_word import word
#DEFAULT VALUES
score = 0
count = 0
win_count = 2
WINDOW_BG = '#e5404e'
WINDOW_SIZE = '1200x870+300+80'
FONT = ('Arial', 40)
#this is an example with only one button
buttons = [['b1','a',80,740]]
#Creating window and configurating it
window = Tk()
window.geometry(WINDOW_SIZE)
window.title('Hangman')
window.config(bg = WINDOW_BG)
#generates all of the labels for the word
def gen_labels_word():
label = Label(window, text = " ", bg = WINDOW_BG, font = FONT)
label.pack( padx = 40,pady = (500,100),side = LEFT)
label1 = Label(window, text = word[0], bg = WINDOW_BG, font = FONT)
label1.pack( padx = 41,pady = (500,100),side = LEFT)
x = 21
for var in range(1,len(word)):
exec('label{}=Label(window,text="_",bg=WINDOW_BG,font=FONT)'.format(var))
exec('label{}.pack(padx = {}, pady = (500,100), side=LEFT)'.format(var,x))
x += 1
exec('label{} = Label(window, text = "{}", bg = WINDOW_BG, font = FONT)'.format(len(word),word[-1]))
exec('label{}.pack( padx = {},pady = (500,100),side = LEFT)'.format(len(word), x+1))
# ---------------------------------------------------------------------------------------------------------------------------------------------------
gen_labels_word()
#----------------------------------------------------------------------------------------------------------------------------------------------------
#letters icons(images)
#hangman (images)
hangman = ['h0','h1','h2','h3','h4','h5','h6']
for var in hangman:
exec(f'{var}=PhotoImage(file="{var}.png")')
han = [['label0','h0'],['label1','h1'],['label2','h2'],['label3','h3'],['label4','h4'],['label5','h5'],['label6','h6']]
for p1 in han:
exec('{}=Label(window, bg = WINDOW_BG ,image={})'.format(p1[0],p1[1]))
exec('label0.place(x = 620,y = 0)')
for var in letters:
exec(f'{var}=PhotoImage(file="{var}.png")')
for var in buttons:
exec(f'{var[0]}=Button(window,bd=0,command=lambda: game_brain("{var[0]}","{var[1]}"),bg = WINDOW_BG,font=FONT,image={var[1]})')
exec('{}.place(x={},y={})'.format(var[0],var[2],var[3]))
def game_brain(button, letter):
global count,win_count,score
exec('{}.destroy()'.format(button))
if letter in word:
for i in range(1,len(word)):
if word[i] == letter:
win_count += 1
exec(f'label{i}.config(text="{letter}")')
if win_count == len(word):
score += 1
messagebox.showinfo('GOOD JOB, YOU WON!\n GOODBYE!')
window.destroy()
else:
count += 1
exec('label{}.destroy()'.format(count-1))
exec('label{}.place(x={},y={})'.format(count,620,0))
if count == 6:
messagebox.showinfo('GAME OVER','YOU LOST!\nGOODBYE!')
window.destroy()
def EXIT():
answer = messagebox.askyesno('ALERT','Do you want to exit the game?')
if answer == True:
window.destroy()
e1 = PhotoImage(file = 'exit.png')
ex = Button(window,bd = 0,command = EXIT,bg = WINDOW_BG,font = FONT,image = e1)
ex.place(x=1050,y=20)
#-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
window.mainloop()
Why exec function in python adds '.!' at the beginning of the text?
The exec function isn't doing that. Tkinter by default names all of its widgets with a leading exclamation point. When you print out a widget, it has to be converted to a string. For tkinter widgets, the result of str(some_widget) is the widget's name.
You can see this quite easily without exec:
import tkinter as tk
root = tk.Tk()
label = tk.Label(root)
print(label)
The above will print something like .!label. If you create a second label it will be .!label2, a third will be .!label3 and so on.
On an unrelated note, you shouldn't be using exec to create widgets. It makes the code very hard to understand and debug. If you want to create widgets in a loop, add them to a dictionary or list instead of dynamically creating variables with exec.
For example:
labels = {}
for var in range(1,len(word)):
label = Label(window,text="_",bg=WINDOW_BG,font=FONT)
label.pack(padx=500, pady=100)
labels[var] = label
With that, you can later reference the widgets as labels[1], labels[2], etc.
You should do the same thing with the images, or anything else that you create in a loop and want to keep track of.

I'm unable to get a string out of tkinter entrybox

import random
import tkinter as tk
frame = tk.Tk()
frame.title("koeweils baldadige encyptor")
frame.geometry('400x200')
printButton = tk.Button(frame,text = "Print", command = lambda: zandkasteel())
printButton.pack()
freek = tk.Text(frame,height = 5, width = 20)
freek.pack()
input_a = freek.get(1.0, "end-1c")
print(input_a)
fruit = 0
fad = input_a[fruit:fruit+1]
print(fad)
schepje = len(input_a.strip("\n"))
print(schepje)
def zandkasteel():
lbl.config(text = "Ingevulde string: "+input_a)
with open("luchtballon.txt", "w") as chocoladeletter:
for i in range(schepje):
n = random.randint()
print(n)
leuk_woord = ord(fad)*n
print(leuk_woord)
chocoladeletter.write(str(leuk_woord))
chocoladeletter.write(str(n))
chocoladeletter.write('\n')
lbl = tk.Label(frame, text = "")
lbl.pack()
frame.mainloop()
I need to get the string that was entered into the text entry field freek. I have tried to assign that string to input_a, but the string doesn't show up.
Right now, input_a doesn't get anything assigned to it and seems to stay blank. I had the same function working before implementing a GUI, so the problem shouldn't lie with the def zandkasteel.
To be honest I really don't know what to try at this point, if you happen to have any insights, please do share and help out this newbie programmer in need.
Here are some simple modifications to your code that shows how to get the string in the Text widget when it's needed — specifically when the zandkasteel() function gets called in response to the user clicking on the Print button.
import random
import tkinter as tk
frame = tk.Tk()
frame.title("koeweils baldadige encyptor")
frame.geometry('400x200')
printButton = tk.Button(frame, text="Print", command=lambda: zandkasteel())
printButton.pack()
freek = tk.Text(frame, height=5, width=20)
freek.pack()
def zandkasteel():
input_a = freek.get(1.0, "end-1c")
print(f'{input_a=}')
fruit = 0
fad = input_a[fruit:fruit+1]
print(f'{fad=}')
schepje = len(input_a.strip("\n"))
print(f'{schepje=}')
lbl.config(text="Ingevulde string: " + input_a)
with open("luchtballon.txt", "w") as chocoladeletter:
for i in range(schepje):
n = random.randint(1, 3)
print(n)
leuk_woord = ord(fad)*n
print(leuk_woord)
chocoladeletter.write(str(leuk_woord))
chocoladeletter.write(str(n))
chocoladeletter.write('\n')
lbl = tk.Label(frame, text="")
lbl.pack()
frame.mainloop()

My variable will not change in function

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.

Python Tkinter StringVar issues

I am trying to make a simple calculator for a game I play as a random project. I found myself very confused on how to go about doing this; I want the user to enter a number in the textbox and it will multiply that number by 64000 and display it in a label above. But, I cannot find out anywhere how to do this. This is just a small practice thing and im amazed I cannot figure it out. Please help meh! Here is my code:
from Tkinter import *
####The GUI#####
root = Tk()
#Title#
root.wm_title("TMF Coin Calculator")
####The Widgets####
a = StringVar()
b = StringVar()
def multiply_a():
d = (int(a) * 64000)
e = str(d)
b.set(e)
b.trace("w", multiply_a)
#Top Label#
top_label = Label(root, fg="red", text="Type the ammount of Coin Stacks you have.")
top_label.grid(row=0, column=0)
#The Output Label#
output_label = Label(root, textvariable=b, width = 20)
output_label.grid(row = 1, column=0)
#User Entry Box#
user_input_box = Entry(root, textvariable=a, width=30)
user_input_box.grid(row=2, column=0)
root.mainloop()
You need to trace the variable that changes: a. Then you need to define multiply_a() to handle an arbitrary number of arguments with *args (happens to be 3 arguments in this case, but *args is fine here).
Go from:
def multiply_a():
d = (int(a) * 64000)
e = str(d)
b.set(e)
b.trace("w", multiply_a)
to:
def multiply_a(*args):
try:
myvar = int(a.get())
except ValueError:
myvar = 0
b.set(myvar * 64000)
a.trace("w", multiply_a)
This will additionally use 0 if the entered value can't be turned into an int.

Categories