Function to generate random string with nested function is giving me trouble - python

I'm gonna preface this by saying that im quite new to this, dont judge haha.
The script im writing is to make a random password from different strings and randomize them. That I have already succeeded in completing, but know that I want to build a GUI for that script, the implementation with functions and tkinter is giving me trouble. I have two functions: One (add2all)that is supposed to check wether a variable is true, and if it is true add it to the string "all", that im later going to randomize with my second function. Im sure there are problems with how I get the value from the Checkbuttons (used to get the user input what kind of characters they want in the password), and then how they are added to the string. My second function (pwdgen) is supposed to get the input length from an Entry box were the user types an int, and then calls the add2all function to see what characters the user wants. add2all should generate a string with all the charracters that have been defined as true, so that pwdgen can randomize them with the given length. I also have a Button that is supposed to start the process. It calls on pwdgen, which then ccalls add2all and at the end, the variable password should have a randomized string which I can display to an entry box.
TL;DR: The function and tkinter implementation of a very simple script I previously wrote isn't working at all.
import random
from tkinter import *
from tkinter import ttk
root = Tk()
upper, lower, nums, syms = False, False, False, False
uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lowercase = "abcdefghijklmnopqrstuvwxyz"
digits = "1234567890"
symbols = "!§$%&?*+#~-;()/"
all = StringVar()
CheckBool1 = IntVar()
CheckBool2 = IntVar()
CheckBool3 = IntVar()
CheckBool4 = IntVar()
pwlength = IntVar()
#function that checks if a CheckButton input (which characters are wanted in password)
#is true, if true adds the corresponding character string to the all string
def add2all():
if CheckBool1:
upper = True
if CheckBool2:
lower = True
if CheckBool3:
nums = True
if CheckBool4:
syms = True
if upper:
all += uppercase
if lower:
all += lowercase
if nums:
all += digits
if syms:
all += symbols
#function that gets password length from user, then calls add2all, then gives var password
#the string of all randomized with specified length and then puts it into entry box pwdoupt
def pwdgen():
pwdoutpt.delete(0, END)
v = amt.get()
v = pwlength
add2all()
password = "".join(random.choices(all, k=pwlength))
pwdoutpt.insert(0, password)
greet = Label(root, text="Welcome to the interactive password generator!", height=3)
pwdoutpt = Entry(root, width=30)
generate = Button(root, text="Generate", command = lambda: pwdgen())
#inits all the labels and checkbuttons for my gui
chck_1 = Checkbutton(root, width = 5, var = CheckBool1)
chck_2 = Checkbutton(root, width = 5, var = CheckBool2)
chck_3 = Checkbutton(root, width = 5, var = CheckBool3)
chck_4 = Checkbutton(root, width = 5, var = CheckBool4)
lbl_1 = Label(root, text="Capital Letters")
lbl_2 = Label(root, text="Lowercase Letters")
lbl_3 = Label(root, text="Digits")
lbl_4 = Label(root, text="Symbols")
amt = Entry(root, width = 5)
amtlbl = Label(root, text="Num of characters in pwd.")
sep = ttk.Separator(root, orient="horizontal")
greet.grid(column=0, row=0, columnspan=4, pady=3)
pwdoutpt.grid(column=0, row=7, columnspan=4, padx=30, sticky=W)
amt.grid(column=0, row=1, sticky=W)
amtlbl.grid(column=1, row=1, columnspan=1, sticky=E)
chck_1.grid(column=0, row=2, sticky=E)
chck_2.grid(column=0, row=3, sticky=E)
chck_3.grid(column=0, row=4, sticky=E)
chck_4.grid(column=0, row=5, sticky=E)
lbl_1.grid(column=1, row=2, columnspan=1, sticky=W)
lbl_2.grid(column=1, row=3, columnspan=1, sticky=W)
lbl_3.grid(column=1, row=4, columnspan=1, sticky=W)
lbl_4.grid(column=1, row=5, columnspan=1, sticky=W)
sep.grid(column=0, columnspan=10, row=6, sticky=EW)
generate.grid(column=2, row=7)
root.mainloop()

Firstly, don't use all as the variable name for your StringVar; it's a built-in python function. Don't use wildcard imports (from <module> import *), it's a bad habit and doesn't conform to PEP8. Instead, use import tkinter as tk.
You need to read how to use a StringVar; it is NOT a string and you can't add to it like one. A good application of using a StringVar in this code would be to display the generated password. If you bind the StringVar to your pwdoutpt Entry, updating the StringVar will automatically display the updated string.
You say you already had your password generator working correctly. Why not slightly adapt your password generator function so it takes the length and character types as inputs, and returns a randomly generated password? You are currently trying to integrate the password generating function into the GUI code, which is a bad idea is it can get messy super fast.
Taking all of the above into consideration, here is a working modified version of your code:
import random
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
# Your password generating function
def pwdgen(password_length, chars_allowed):
chars = [
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"abcdefghijklmnopqrstuvwxyz",
"1234567890",
"!§$%&?*+#~-;()/"
]
valid_chars = [x for i, x in enumerate(chars) if chars_allowed[i] == True]
valid_chars = "".join(valid_chars)
password = "".join(random.choices(valid_chars, k=password_length))
return password
# Set up tkinter window
root = tk.Tk()
root.title("Password generator")
# Vars for checkbuttons and password entry
CheckBool1 = tk.IntVar()
CheckBool2 = tk.IntVar()
CheckBool3 = tk.IntVar()
CheckBool4 = tk.IntVar()
password = tk.StringVar()
# Main widgets
greet = tk.Label(root, text="Welcome to the interactive password generator!", height=3)
chck_1 = tk.Checkbutton(root, width = 5, var = CheckBool1)
chck_2 = tk.Checkbutton(root, width = 5, var = CheckBool2)
chck_3 = tk.Checkbutton(root, width = 5, var = CheckBool3)
chck_4 = tk.Checkbutton(root, width = 5, var = CheckBool4)
lbl_1 = tk.Label(root, text="Capital Letters")
lbl_2 = tk.Label(root, text="Lowercase Letters")
lbl_3 = tk.Label(root, text="Digits")
lbl_4 = tk.Label(root, text="Symbols")
amt = tk.Entry(root, width = 5)
amtlbl = tk.Label(root, text="Num of characters in pwd.")
sep = ttk.Separator(root, orient="horizontal")
# Password output
pwdoutpt = tk.Entry(root, width=30, textvariable=password, state="readonly")
# Generate password function and button
def insert_password():
try:
password_length = int(amt.get())
chars_allowed = [CheckBool1.get(), CheckBool2.get(), CheckBool3.get(), CheckBool4.get()]
password.set(pwdgen(password_length, chars_allowed))
except ValueError:
messagebox.showerror("Error", "Invalid password length")
except IndexError:
messagebox.showerror("Error", "No character type selected")
generate = tk.Button(root, text="Generate", command = insert_password)
# Gridding widgets
greet.grid(column=0, row=0, columnspan=4, pady=3)
pwdoutpt.grid(column=0, row=7, columnspan=4, padx=30, sticky=tk.W)
amt.grid(column=0, row=1, sticky=tk.W)
amtlbl.grid(column=1, row=1, columnspan=1, sticky=tk.E)
chck_1.grid(column=0, row=2, sticky=tk.E)
chck_2.grid(column=0, row=3, sticky=tk.E)
chck_3.grid(column=0, row=4, sticky=tk.E)
chck_4.grid(column=0, row=5, sticky=tk.E)
lbl_1.grid(column=1, row=2, columnspan=1, sticky=tk.W)
lbl_2.grid(column=1, row=3, columnspan=1, sticky=tk.W)
lbl_3.grid(column=1, row=4, columnspan=1, sticky=tk.W)
lbl_4.grid(column=1, row=5, columnspan=1, sticky=tk.W)
sep.grid(column=0, columnspan=10, row=6, sticky=tk.EW)
generate.grid(column=2, row=7)
root.mainloop()
Some further notes on the code for you:
The function insert_password uses a try except to test if the inputs are correct before generating the password.
pwdoutpt has state="readonly" so that the user can't modify the generated password but can still copy it

Related

Restart script on button press using tkinter

I have a simple script to convert Degree Minute Second to Decimal Degree, using tkinter with a simple GUI. The script waits for the user to click the "Calculate" button before proceeding, to ensure values have been entered in the required 'tk.Entry' fields, then displays the calcuated output.
How would I implement a "Reset" button to allow for another calculation to be run?
I was thinking a while loop for my entire script but don't understand how to implement it.
Apologies for the elementary question, this is my first attempt at using tkinter / GUI, it was much easier to add a re-run while loop to the commandline version of my script.
edit: the "Reset" button currently does nothing, it's just for placement.
# Check python version and import correct tkinter.
import string
import sys
if (sys.version_info.major == 3):
print("Python 3")
import tkinter as tk# for Python 3
else:
print("Python 2")
import Tkinter as tk# for Python 2.7
# Configure tkinter window name, size, colour, columns.
root = tk.Tk()
root.title("CCT")
root.resizable(False, False)
root.attributes("-alpha", 0.95)
root.config(bg = "#F5F5F5")
# Label for top of application.
label_info = tk.Label(root, text="Coordinate Conversion Tool", pady = 5, bg = "#e8e8e8", padx=10)
label_info.grid(row=0, column=0, columnspan=4, sticky = tk.W+tk.E, pady=(0,10))
# Label and entry for degree.
label_d = tk.Label(text="Degree ->", bg = "#F5F5F5")
label_d.grid(row=1, column=0, columnspan=2, sticky = tk.W, padx=(10,0))
entry_d = tk.Entry(root, width=10, bg = "#e8e8e8")
entry_d.grid(row=1, column=2, columnspan=2, sticky = tk.E, padx=(0,10))
# Label and entry for minute.
label_m = tk.Label(text="Minute ->", bg = "#F5F5F5")
label_m.grid(row=2, column=0, columnspan=2, sticky = tk.W, padx=(10,0))
entry_m = tk.Entry(root, width=10, bg = "#e8e8e8")
entry_m.grid(row=2, column=2, columnspan=2, sticky = tk.E, padx=(0,10))
# Label and entry for second.
label_s = tk.Label(text="Second ->", bg = "#F5F5F5")
label_s.grid(row=3, column=0, columnspan=2, sticky = tk.W, padx=(10,0))
entry_s = tk.Entry(root, width=10, bg = "#e8e8e8")
entry_s.grid(row=3, column=2, columnspan=2, sticky = tk.E, padx=(0,10))
# Radiobutton for quadrant selection.
def retrieve():
print(quadrant_var.get())
quadrant_var = tk.StringVar(value = "N")
quad_button_n = tk.Radiobutton(root, text = "N", variable = quadrant_var, value = "N", command = retrieve, pady = 3)
quad_button_n.grid(row=4, column=0)
quad_button_e = tk.Radiobutton(root, text = "E", variable = quadrant_var, value = "E", command = retrieve, pady = 3)
quad_button_e.grid(row=4, column=1)
quad_button_s = tk.Radiobutton(root, text = "S", variable = quadrant_var, value = "S", command = retrieve, pady = 3)
quad_button_s.grid(row=4, column=2)
quad_button_w = tk.Radiobutton(root, text = "W", variable = quadrant_var, value = "W", command = retrieve, pady = 3)
quad_button_w.grid(row=4, column=3)
# Set blank variable for wait_variable
var = tk.IntVar()
# Button for calculating the conversion with wait_variable
calculate = tk.Button(text="Calculate", command=lambda: var.set(1))
calculate.grid(row=5, column=0, columnspan=2, sticky = tk.E+tk.W, padx=10, pady=10)
# Button to reset and allow for another calculation
calculate = tk.Button(text="Reset")
calculate.grid(row=5, column=2, columnspan=2, sticky = tk.E+tk.W, padx=10, pady=10)
# Label with placeohlder output text
label_output = tk.Label(text=" ", borderwidth=2, relief="groove", font="Arial, 12", pady=8)
label_output.grid(row=7, column=0, columnspan=4, sticky = tk.W+tk.E, padx=10)
# Label at the bottom of the application
label_foot = tk.Label(text="Developed by Ryan Seabrook", bg = "#F5F5F5", fg = "#7a7a7a", pady = 1)
label_foot.grid(row=8, column=0, columnspan=4, sticky = tk.W+tk.E)
# Wait for the user to press the calculate button.
calculate.wait_variable(var)
# Information from user input for degree minute second, converted to float for math calculation.
degree = float(entry_d.get())
minute = float(entry_m.get())
second = float(entry_s.get())
# Raw calculated output for DMS to DD.
calculated_dd = (float(degree) + (float(minute)/60) + (float(second)/3600))
# Rounded DD output.
rounded_dd = round(calculated_dd,8)
# Fetch string for final output
rounded_dd_str = str(rounded_dd)
final_output = "output"
selected_quadrant = quadrant_var.get()
# If statement to assign correct quadrant value to output
if selected_quadrant == "W":
final_output = "-" + rounded_dd_str + " " + selected_quadrant
elif selected_quadrant == "S":
final_output = "-" + rounded_dd_str + " " + selected_quadrant
else:
final_output = rounded_dd_str + " " + selected_quadrant
# Label for final output
label_output = tk.Label(text=final_output, borderwidth=2, relief="sunken", font="Arial 12", pady=8)
label_output.grid(row=7, column=0, columnspan=4, sticky = tk.W+tk.E, padx=10)
# Holds python while tkinter root window is open.
root.mainloop()
There seems to be a related post here,
Restart program tkinter
which also links to this code snippet on this page,
https://www.daniweb.com/programming/software-development/code/260268/restart-your-python-program
which may solve your problem.
I hope this helps!

Values not stored in Tkinter Variables

In my code, I have tried to get the user input through text fields, store them in variables and finally print them in a tabular form.
The problem I am facing is that none of the values I enter through the text fields get displayed; when I try printing the variables, they come up empty.
Here's part of my code:
# SPASC
from tkinter import *
import tkinter as tk
import tkinter.ttk as tktrv
root = tk.Tk()
root.title("SPASC")
root.geometry("410x400")
lb1 = Label(root, text="SPASC \n Welcomes You !!!", fg="red", bg="sky blue"
, font=('Arial Black', 20), width=22, anchor=CENTER)
lb2 = Label(root, text="What would you like to compare?",
font=('Arial', 18), anchor=CENTER)
space1 = Label(root, text="\n\n")
lb1.grid(row=0)
lb2.grid(row=5)
space1.grid(row=1)
hpw, mil = StringVar(), StringVar()
def bt_cars():
w1 = Toplevel()
w1.title("Choose Features")
w1.geometry("430x200")
lb3 = Label(w1, text="Choose features for comparison", bg="yellow"
, font=('Arial Black', 18), width=25)
lb4 = Label(w1, text=" ", anchor=CENTER)
fr1 = LabelFrame(w1, width=20, padx=100)
hpw_cb = Checkbutton(fr1, text="Horsepower", variable=hpw, anchor='w', onvalue="Horsepower", offvalue="")
hpw_cb.grid()
hpw_cb.deselect()
mil_cb = Checkbutton(fr1, text="Mileage", variable=mil, anchor='w', onvalue="Mileage", offvalue="")
mil_cb.grid()
mil_cb.deselect()
var_stor = [hpw, mil]
print(hpw)
print(mil)
var_fill = []
for itr1 in var_stor:
if itr1 != "":
var_fill.append(itr1)
print(var_fill)
def car_1():
name1 = StringVar()
c1 = Toplevel()
c1.title("Car 1")
c1.geometry("430x200")
car1_lb1 = Label(c1, text="Car Name:")
name1_ifl = Entry(c1)
name1 = name1_ifl.get()
elm_var_fill = len(var_fill)
ct1 = 0
car1_val = []
for itr2 in var_fill:
if ct1 == elm_var_fill:
break
lb5 = Label(c1, text=itr2.get())
#Creating text field
ftr1_ifl = Entry(c1)
car1_ftr = ftr1_ifl.get()
car1_val.append(car1_ftr)
car1_ftr = None
lb5.grid(row=ct1 + 2, column=1)
ftr1_ifl.grid(row=ct1 + 2, column=2)
ct1 += 1
print(car1_val)
def display():
dp = Toplevel()
dp.title("Results")
dp.geometry("500x200")
car1_pt = 0
car2_pt = 0
car_tree = tktrv.Treeview(dp)
car_tree["columns"] = ("car1col")
car_tree.column("#0", width=120, minwidth=30)
car_tree.column("car1col", width=120, minwidth=30)
car_tree.heading("#0", text="Features" )
car_tree.heading("car1col", text=str(name1))
car_tree.pack()
c1.withdraw()
print(var_fill)
done1_bt = Button(c1, text="Continue", command=display)
name1_ifl.grid(row=0, column=2)
car1_lb1.grid(row=0, column=1)
done1_bt.grid(row=5,column=1)
w1.withdraw()
done_bt = Button(w1, text="Done", command=car_1)
done_bt.grid(row=3, column=1)
lb3.grid(row=0, column=1)
lb4.grid(row=1, column=1)
fr1.grid(row=2, column=1)
root.withdraw()
bt1 = Button(root, text="CARS", width=5, font=('Calibri', 15), command=bt_cars)
bt1.grid(row=7)
space2 = Label(root, text="\n\n")
space2.grid(row=6)
root.mainloop()
I am facing trouble with the variables named: hpw, mil, name1.
Any help would be welcome.
NOTE:- Please excuse the amount of code; I wanted others to replicate the error and see it for themselves
For the variables hpw and mil, these variables are empty strings that's why you are not getting any value from those checkboxes. To get values from the checkboxes replace these lines of code:
var_stor = [hpw, mil]
with
var_stor = [hpw_cb.cget('onvalue'), mil_cb.cget('onvalue')]
since you want the onvalue then you must use cget() method to access those values.
also, replace
lb5 = Label(c1, text=itr2.get())
with
lb5 = Label(c1, text=itr2)
because now you have required values (not objects) in a list, so just need to access those values.
For the variable name1 you can use #BokiX's method.
The problem is you are using get() wrong. You cannot use get() right after Entry() because as soon as entry is created it's getting the input before the user can even input something.
Use this code:
def get_input(text):
print(text)
e = Entry(root)
e.pack()
b = Button(root, text="Print input", command=lambda: get_input(e.get()))
b.pack()
Now get() method will not be executed before you click the button.

Solving problem to generate custom number from inserted values with GUI in Python

Hello im having python learning project. I want to insert in GUI two numbers, which are defining range for program to generate random number from.
I am really having problems with calling function with press of the button. And constantly getting error ValueError: invalid literal for int() with base 10: '', when trying to convert string from entry in GUI to int and then inserting them into random.randint.
Thx for Help!
from tkinter import *
import random
root = Tk()
root.title("Generator custom random number")
#function that gets number from entry converts string to int and defines target number in stevilo
def function():
string_answer1 = prvo_stevilo.get()
int1 = int(string_answer1)
string_answer2 = drugo_stevilo.get()
int2 = int(string_answer2)
stevilo = random.randint(int1, int2)
#Defining GUI
navodilo = Label(root, text="Choose custom lower and upper number to chose random number from", width=60)
navodilo2 = Label(root, text="From", width=20, borderwidth=3)
navodilo3 = Label(root, text="To", width=20, borderwidth=3)
prvo_stevilo = Entry(root, width=20, borderwidth=3)
drugo_stevilo = Entry(root, width=20, borderwidth=3)
gumb = Button(root, text="Generate number", width=17, height=2, command=function)
praznavrstica = Label(root, text="")
izpis = Label(root, text="Random number is: ", width=20)
izpis_stevila = Label(root, text="" + stevilo)
#Showcase of gui
navodilo.grid(row=0, column=0, columnspan=1)
navodilo2.grid(row=1, column=0, columnspan=1)
navodilo3.grid(row=3, column=0, columnspan=1)
prvo_stevilo.grid(row=2, column=0, columnspan=1)
drugo_stevilo.grid(row=4, column=0, columnspan=1)
praznavrstica.grid(row=5, column=0, columnspan=1)
gumb.grid(row=6, column=0, columnspan=1)
praznavrstica.grid(row=7, column=0, columnspan=1)
izpis.grid(row=8, column=0, columnspan=1)
izpis_stevila.grid(row=9, column=0, columnspan=1)
#Loop
root.mainloop()
I've noticed few problems with your code. I was able to make it running without too many changes, although probably it is not the best way.
First answer to your question: you are getting this error, because you are trying to change string -> '' to int. It happens because function() is running before you click button.
Another problem:
izpis_stevila = Label(root, text="" + stevilo)
variable 'stevilo' simply doesn't exist before calling function(), so delete it from here.
My proposition for changes:
1)
gumb = Button(root, text="Generate number", width=17, height=2,command = lambda: function())
Without lambda your function will run no matter of state of your button.
2)
first = IntVar(root, value=0)
second = IntVar(root, value=1)
prvo_stevilo = Entry(root, width=20, borderwidth=3, textvariable=first)
drugo_stevilo = Entry(root, width=20, borderwidth=3, textvariable=second)
If you run function without any values in your entry you will get error. This change allows you to put default value for your entry widgets.
3)
def function():
if prvo_stevilo.get() == '' or drugo_stevilo.get() =='':
return
else:
string_answer1 = prvo_stevilo.get()
int1 = int(string_answer1)
string_answer2 = drugo_stevilo.get()
int2 = int(string_answer2)
stevilo = random.randint(int1, int2)
izpis_stevila = Label(root, text=str(stevilo))
izpis_stevila.grid(row=9, column=0)
Firstly check if your entry is not empty.
Secondly update label, also remeber about changing int to string here text=str(stevilo).

How to Get Iterations to Update with addition to list

So I've been struggling with an issue for a week or so, been googling around trying to find different solutions, etc and getting nowhere. I was advised to put functioning code on here so I've cut it down some while still showing the issue.
I want to have a main page listing a set of goals, then if you click on the "Goal Entry" button up top a new window opens where you can input additional goals. Then you type in your desired additions, hit enter, and it adds it to the list on the main page.
I've accomplished all of the above EXCEPT, after you add the goals (and I have the list printing before and after so I know they're being added) and the entry window closes, the list of labels (created by an iteration) hasn't updated accordingly.
How do I get the list on the main page to automatically update when a new item is added to the list?
from tkinter import *
pg = ["goal1","goal2"]
pgtotal=1
psum=len(pg)
class yeargoals():
global pg, hg, fg, rg, rgtotal
def __init__(self,master):
self.master = master
master.title("This Year's Goals")
self.buttonframe = Frame(root)
self.buttonframe.pack(side=TOP, padx = 150, fill=BOTH)
self.home = Button(self.buttonframe, text="Home Page")
self.home.grid(row=1, column=1, padx=10)
self.enter = Button(self.buttonframe, text="Goal Entry", command=self.winenter)
self.enter.grid(row=1, column=2, padx=10)
self.finalize = Button(self.buttonframe, text="Finalize for Year")
self.finalize.grid(row=1, column=3, padx=10)
self.dashboard = Button(self.buttonframe, text="Goal Dashboard")
self.dashboard.grid(row=1,column=4, padx=10)
self.goalframe = Frame(root)
self.goalframe.pack(side=TOP, padx=150, pady=50, fill=BOTH, expand = True)
#Makes the label Fram I want the Checkboxes to go in
self.LabelFramep= LabelFrame(self.goalframe,text="Professional Goals")
self.LabelFramep.pack(side=LEFT, padx=10, anchor = N, fill=BOTH, expand = True)
#Makes the from the list above
for goal in pg:
l = Checkbutton(self.LabelFramep, text=goal, variable=Variable())
l.config(font=("Courier",12))
l.grid(sticky=W)
self.ptotal=Label(self.LabelFramep,text="Progress so far: "+str(pgtotal)+"/"+str(psum))
self.ptotal.config(font=("Courier",12))
self.ptotal.grid(sticky=W)
self.pper=Label(self.LabelFramep, text=str(round((pgtotal/psum)*100))+"% Complete")
self.pper.config(font=("Courier",12))
self.pper.grid(sticky=W)
def winenter(self):
global pg
self.winenter = Toplevel(root)
options = ["Professional", "Health", "Financial", "Reward Items"]
variable = StringVar(self.winenter)
variable.set(options[0])
#Title of entry section
t1 = Label(self.winenter, text="New Goal Entry")
t1.grid(row=0, column=1, columnspan=2)
#dropdown menu
d = OptionMenu(self.winenter, variable, *options)
d.grid(row=1, column=2)
#entry fields
e1 = Entry(self.winenter)
e1.grid(row=2, column=2, padx = 10, pady=5)
e2 = Entry(self.winenter)
e2.grid(row=3, column=2, padx=10, pady=5)
e3 = Entry(self.winenter)
e3.grid(row=4, column=2, padx=10, pady=5)
e4 = Entry(self.winenter)
e4.grid(row=5, column=2, padx=10, pady=5)
e5 = Entry(self.winenter)
e5.grid(row=6, column=2, padx=10, pady=5)
#Label for entry fields
l1 = Label(self.winenter, text="Goal Number 1")
l1.grid(row=2, column=1)
l2 = Label(self.winenter, text="Goal Number 2")
l2.grid(row=3, column=1)
l3 = Label(self.winenter, text="Goal Number 3")
l3.grid(row=4, column=1)
l4 = Label(self.winenter, text="Goal Number 4")
l4.grid(row=5, column=1)
l5 = Label(self.winenter, text="Goal Number 5")
l5.grid(row=6, column=1)
def enter():
global pg, main
print (pg)
if variable.get() == "Professional":
pg.append(e1.get())
self.winenter.destroy()
print (pg)
#Goal entry execute button
b = Button(self.winenter, text="Enter Goals", command=enter)
b.grid(row=7, column = 1)
root = Tk()
Window = yeargoals(root)
root.mainloop()
In your callback function to button "Enter Goals", you have done nothing to update your main window. Maybe you think the main window will magically keep updated with the variable pg, no, you need to do all those updates manually in your callback function.
For example, change your callback enter() to:
def enter():
global pg, main
print (pg)
if variable.get() == "Professional":
pg.append(e1.get())
l = Checkbutton(self.LabelFramep, text=pg[-1], variable=Variable())
l.config(font=("Courier",12))
l.grid(sticky=W)
self.winenter.destroy()
print (pg)
You can find the main window is updated after you click "Enter Goals".

How to get the value of the selected radio button?

I would like to create 2 different groups of radio buttons. The user would select one option from either group. There would be a function that would get the values(strings) from the selected radio buttons and then print them. Here's my code but it doesn't work (i'm new to python).
from tkinter import *
root = Tk()
btn1 = "lol"
btn2 = "lel"
def funkcija():
n = entry1.get()
m = "null"
X = btn1.get()
Y = btn2.get()
print("%s %s je %s %s." % (n, X, m, Y))
theLabel = Label(root, text="Vnesite količino in izberite prvo valuto.")
theLabel.grid(row=0, columnspan=3)
gumb1=Radiobutton(root,text="Euro",value = "euro",variable = "btn1").grid(row=2, column=1, sticky=W)
gumb2=Radiobutton(root,text="Dolar",value = "dolar",variable = "btn1").grid(row=3, column=1, sticky=W)
gumb3=Radiobutton(root,text="Funt",value = "funt",variable = "btn1").grid(row=4, column=1, sticky=W)
label3= Label(root, text="Izberite drugo valuto.")
label3.grid(row=6, columnspan=3)
label35= Label(root)
label35.grid(row=5, columnspan=3)
gumb4=Radiobutton(root,text="Euro",value = "euro",variable = "btn2").grid(row=7, column=1, sticky=W)
gumb5=Radiobutton(root,text="Dolar",value = "dolar",variable = "btn2").grid(row=8, column=1, sticky=W)
gumb6=Radiobutton(root,text="Funt",value = "funt",variable = "btn2").grid(row=9, column=1, sticky=W)
label1 = Label(root, text="Količina:")
label1.grid(row=1, sticky=E)
entry1 = Entry(root)
entry1.grid(row=1, column=1, sticky=W)
go = Button(root, text="Izračun", fg="white", bg="black", command=funkcija)
go.grid(row=10, columnspan=3)
root.mainloop()
In your radio button, analyze the parameters that you are passing:
gumb1 = Radiobutton(root,
text = "Euro",
value = "Euro",
variable = "btn2"
The parameters value and variable are what stores the data of the radio button. You've set your value option correctly. The interpreter will automatically set the variable with the value when the radio button is selected.
But here's where your issue is:
variable = "btn2"
"btn2" is a string. Not very useful though, is it? In fact, you're trying to perform methods on it that don't even exist. Such as here:
def funkcija():
X = btn2.get()
In fact, taking this information, you almost got there!
At the top of your script, you need to set btn2 to Tkinter's StringVar, like so:
from tkinter import *
btn1 = StringVar()
btn2 = StringVar()
Now that's done, let's change our parameters in our radio buttons.
gumb1 = Radiobutton(root,
text = "Euro",
value = "Euro",
variable = btn2
Now, Tkinter will automatically update the variable when it is selected. To get the value, do the same that you had done in your funkcija.
X = btn2.get()
And then the value of btn2 (which was updated by the radio buttons) will not be read, and stored into the variable X.

Categories

Resources