Tkinter Option menu and config - python

I am trying to make a GUI that have two dropdown menus and a text label.
The value selected in the first dropdown menu should update the list of options in the second dropdown menu. (this part of the code works correctly!).
Then, once the user select a value from the second dropdown menu the text label should update. I am trying to update the text label with a using the config method, but it does not seem to work. any ideas?
import tkinter as tk
from tkinter import *
root = Tk()
root.title("My app")
root.minsize(width=330,height=280)
options1 = ["Option 1","Option 2"]
options2 = [""]
options21 =["Option 1.1","Option 1.2","Option 1.3","Option 1.4"]
options22 = ["Option 2.1","Option 2.2","Option 2.3","Option 2.4"]
labelvuot=Label(root,text= " ")
def weigthtxt(event):
if om2.get() == "":
pass
else:
mydamage = int(om2.get().split(".")[1])
if mydamage == 1:
labelweigth.config(text="1")
elif mydamage == 2:
labelweigth.config(text="2")
elif mydamage == 3:
labelweigth.config(text="3")
elif mydamage == 4:
labelweigth.config(text="4")
else:
labelweigth.config(text="No number")
def add_option(self):
om2.set("")
labelweigth.config(text="")
answer = om1.get()
global options2
options2.clear()
if answer == "Option 1":
options2 = options2+options21
menu = drop2["menu"]
menu.delete(0, "end")
for x in options2:
menu.add_command(label=x,
command=lambda value=x: om2.set(value))
elif answer == "Option 2":
options2 = options2 + options22
menu = drop2["menu"]
menu.delete(0, "end")
for x in options2:
menu.add_command(label=x,
command=lambda value=x: om2.set(value))
def save():
element = om1.get()
damage = om2.get()
inten = r1.get()
exten = r2.get()
pergiu = r3.get()
txt = note.get(1.0,END)
print(element,damage,inten,exten,pergiu,txt,int(om2.get().split(".")[1]))
label1=Label(root,text= "Select Element").grid(row=1,column=3)
labelvuot.grid(row=1,column=5)
om1 = tk.StringVar()
om1.set("")
drop = tk.OptionMenu(root, om1, *options1, command= add_option)
drop.config(width=20)
drop.grid(row=1,column=7,columnspan=3)
label2=Label(root,text= "Damage Type").grid(row=2,column=3)
om2 = tk.StringVar()
om2.set("")
drop2 = tk.OptionMenu(root,om2, *options2,command=weigthtxt)
drop2.config(width=20)
drop2.grid(row=2,column=7,columnspan=3)
label3=Label(root,text= "Weigth").grid(row=3,column=1,columnspan=3)
labelweigth = Label(root,text="")
labelweigth.grid(row=3,column=7,columnspan=3)
root.mainloop()

tkinter module has an internal class _setit which is used by tk.OptionMenu class when setting up the menu actions.
You need to use this internal class when you populate the menu items inside add_option() function:
...
# it is executed when item of second dropdown menu is selected
def weigthtxt(value):
if value:
mydamage = int(value.split(".")[1])
if mydamage == 1:
labelweigth.config(text="1")
elif mydamage == 2:
labelweigth.config(text="2")
elif mydamage == 3:
labelweigth.config(text="3")
elif mydamage == 4:
labelweigth.config(text="4")
else:
labelweigth.config(text="No number")
def add_option(answer):
om2.set("")
labelweigth.config(text="")
options2.clear()
if answer == "Option 1":
options2.extend(options21)
elif answer == "Option 2":
options2.extend(options22)
menu = drop2["menu"]
menu.delete(0, "end")
for x in options2:
menu.add_command(label=x, command=tk._setit(om2, x, weigthtxt))
...

Related

How to implement what I got from checkbutton in tkinter Python

I can't get the values ​​that are selected in the checkbutton.
I want to add text and value to checkbutton.
I have a list variable defined and must be released after I select it.
from tkinter import Tk, Checkbutton, Frame, IntVar
class Options:
def __init__(self, parent, name, selection=None, select_all=False):
self.parent = parent
self.name = name
self.selection = selection
self.variable = IntVar()
self.checkbutton = Checkbutton(self.parent, text=self.name,
variable=self.variable, command=self.check)
if selection is None:
self.checkbutton.pack(side='top')
elif select_all:
self.checkbutton.config(command=self.select_all)
self.checkbutton.pack()
for item in self.selection:
item.checkbutton.pack(side='top')
def check(self):
state = self.variable.get()
if state == 1:
print(f'Selected: {self.name}')
if all([True if item.variable.get() == 1 else False for item in self.selection[:-1]]):
self.selection[-1].checkbutton.select()
elif state == 0:
print(f'Deselected: {self.name}')
if self.selection[-1].variable.get() == 1:
self.selection[-1].checkbutton.deselect()
def select_all(self):
state = self.variable.get()
if state == 1:
for item in self.selection[:-1]:
item.checkbutton.deselect()
item.checkbutton.invoke()
elif state == 0:
for item in self.selection[:-1]:
item.checkbutton.select()
item.checkbutton.invoke()
selection = []
enable = [['name1', 'position1'], ['name2', 'position2'], ['name3', 'position3']]
root = Tk()
option_frame = Frame(root)
option_frame.pack(side='left', fill='y')
for i in range(len(enable)):
selection.append(Options(option_frame,enable[i][0], selection))
selection.append(Options(option_frame, 'Select All', selection, True))
root.mainloop()

How to reuse a Button action

I am trying to reuse the action of this button, without recalling the command all over again, the thing is that, after the button executes the first "if" statement "y == 1".
Now, instead of having access to the second "if" statement "y == 2" (That is, assume the program starts now, if I enter 1 in the entry box and the button is clicked, the program should print "Yes!", then if I enter 2 again in the entry box and the button is clicked, the program should print "Yes!Yes!", but instead it starts the "def action()" all over again)
I want it to run like the second code if I use a console
from tkinter import *
win = Tk()
def action():
y = x.get()
if y == 1:
print("Yes!")
if y == 2:
print("Yes!Yes!")
elif y == 3:
print("Yes!Yes!Yes!")
else:
print("No")
x = IntVar()
e1 = Entry(win, textvariable = x).grid()
b1 = Button(win, text = "Button", command = action).grid()
win.mainloop()
The second code
y = eval(input("Enter a value: "))
if y == 1:
print("Yes")
y = eval(input("Enter a value: "))
if y == 2:
print("Yes!Yes!")
elif y == 3:
print("Yes!Yes!Yes!")
else:
print("No")
put
y = x.get()
clicked = False
after
b1 = Button(win, text = "Button", command = action).grid()
Now,
def action():
if y == 2 and clicked == True:
print("Yes!Yes!")
if y == 3 and clicked == True:
print("Yes!Yes!Yes!")
if y == 1 and clicked == False:
print("Yes!")
clicked = True
If I understood your question well, this might pop the desired result.
Walrus to rescued.
Code:
from tkinter import *
win = Tk()
def action():
# y = x.get()
if (y := x.get()) == 1:
print("Yes!")
elif y == 2:
txt= 'Yes!'
print(txt*2)
elif y == 3:
txt = 'Yes!'
print(txt*3)
else:
print("No")
x = IntVar()
e1 = Entry(win, textvariable = x).grid()
b1 = Button(win, text = "Button", command = action).grid()
win.mainloop()
Result:
Yes!
Yes!Yes!
Yes!Yes!Yes!
No
if I enter 1 in the entry box and the button is clicked, the program
should print "Yes!", then if I enter 2 again in the entry box and the
button is clicked, the program should print "Yes!Yes!", and so on.
Walrus to rescued.
Code:
from tkinter import *
win = Tk()
def action():
# y = x.get()
if (y := x.get()) == 1:
print("Yes!")
elif y == 2:
txt= 'Yes!'
print(txt*2)
elif y == 3:
txt = 'Yes!'
print(txt*3)
else:
print("No")
x = IntVar()
e1 = Entry(win, textvariable = x).grid()
b1 = Button(win, text = "Button", command = action).grid()
win.mainloop()
Result:
Yes!
Yes!Yes!
Yes!Yes!Yes!
No

Show label if combobox value is selectek Tkinter Python3

I need to show/add a label and a textbox when I select a certain value in the combobox. I found this question and it helped but I still didn't get the desired output.
the purpose is the show the label vlan and the textbox when I select the value Single tagged in the combobox.
This is my code :
from tkinter import ttk
from tkinter import messagebox
from tkinter import Tk
from tkinter import Label, Entry, StringVar
root = Tk()
root.title('Traffic generation')
root.geometry('250x250')
ttk.Label(root, text = "Traffic generation",
background = 'light blue', foreground ="white",
font = ("Times New Roman", 15)).grid(row = 0, column = 1, sticky='NESW')
cmb = ttk.Combobox(root, width="10", values=(' Untagged',' Single tagged',' Double tagged'))
def handler(event):
current = cmb.current()
if current == ' Single tagged':
labelText=StringVar()
labelText.set("VLAN")
labelDir=Label(root, textvariable=labelText, height=4)
labelDir.grid(row=2,column=0,sticky='s')
directory=StringVar(None)
dirname=Entry(root,textvariable=directory,width=50)
dirname.grid(row=2,column=1,sticky='e')
#cmb = Combobox
cmb.bind('<<ComboboxSelected>>', handler)
cmb.grid(row=1,column=0,sticky='s')
class TableDropDown(ttk.Combobox):
def __init__(self, parent):
self.current_table = tk.StringVar() # create variable for table
ttk.Combobox.__init__(self, parent)# init widget
self.config(textvariable = self.current_table, state = "readonly", values = ["Customers", "Pets", "Invoices"])
self.current(0) # index of values for current table
self.place(x = 50, y = 50, anchor = "w") # place drop down box
def checkcmbo():
if cmb.get() == " Untagged":
messagebox.showinfo("What user choose", "you chose Untagged")
elif cmb.get() == " Single tagged":
messagebox.showinfo("What user choose", "you choose Single tagged")
elif cmb.get() == " Double tagged":
messagebox.showinfo("What user choose", "you choose Double tagged")
elif cmb.get() == "":
messagebox.showinfo("nothing to show!", "you have to be choose something")
cmb.place(relx="0.1",rely="0.1")
btn = ttk.Button(root, text="Select mode",command=checkcmbo)
btn.place(relx="0.5",rely="0.1")
root.mainloop()
The problem is that Combobox.current() will return the index not the value.
There are two solutions:
change if current == ' Single tagged': to if current == 1.
change if current == ' Single tagged': to if cmb.get() == ' Single tagged':.

TKinter running through a loop

For a basic example, suppose I want to run a list of questions and for each question i want a button to be pressed which will append a value "yes" or "no" to the list.
window = tk.Tk()
app=tk.Frame(window)
app.grid()
response_list = []
y_button = tk.Button(app,text="yes", command=lambda x="yes": appendResponse(x))
n_button = tk.Button(app,text="no", command=lambda x="no": appendResponse(x))
questions=["q1","q2","q3"]
window.mainloop()
How can i make the window stay open and display all the questions until there is a complete list of answers?
You can write a function like the following:
#STARTS HERE
#Label with question
lbl1 = tk.Label(app, text="Are you a human?")
lbl1.grid()
def appendResponse(resp):
global response_list
questionNo = len(response_list)
if questionNo % 3 == 0:
lbl1.configure(text="Is this a valid question?")
elif questionNo % 3 == 1:
lbl1.configure(text="Is there a better way to do this?")
elif questionNo % 3 == 2:
lbl1.configure(text="Is this what you wanted to do?")
response_list.append(resp)
#FINISHES HERE

tkinter: How to change labels inside the program itself

I was asked to edit my code so I decided to include the entire calculator script
from tkinter import *
global choice
choice = 0
#Program
def calculate(*event):
if choice == 1:
try:
add1 = ccalc1.get()
add2 = ccalc2.get()
except:
no = Label(app, text="You must use a number").grid(row=0, column=0)
answ = add1 + add2
answer = Label(app, text = answ).grid(row=1, column=0)
elif choice == 2:
try:
sub1 = ccalc1.get()
sub2 = ccalc2.get()
except:
no = Label(app, text="You must use a number").grid(row=1, column=0)
answ = sub1 - sub2
answer = Label(app, text = answ).grid(row=1, column=0)
def choice2():
global choice
choice = 2
#End Program
#GUI
#Window Info
calc = Tk()
calc.title("Calculator")
calc.geometry("200x140")
#End Window Info
#Build Window
app = Frame(calc)
app.grid()
ccalc1 = IntVar()
ccalc2 = IntVar()
#Widgets
if choice == 0:
welcome = Label(app, text="Select a choice")
elif choice == 2:
welcome.config(text="Subtraction")
calcbox1 = Entry(app,textvariable=ccalc1)
calcbox2 = Entry(app,textvariable=ccalc2)
submit = Button(app, text="CALCULATE", command = calculate)
welcome.grid(row=0,column=0)
calcbox1.grid(row=2, column=0)
calcbox2.grid(row=3, column=0)
submit.grid(row=4, column=0)
calc.bind('<Return>', calculate)
#End Widgets
#Menu
menu=Menu(calc)
#Operations
filemenu = Menu(menu,tearoff=0)
filemenu.add_command(label="Subtract", command = choice2)
menu.add_cascade(label="Operations",menu=filemenu)
calc.config(menu=menu)
calc.mainloop()
#End GUI
what wrong is that the welcome label text wont change accordingly.
Update: I included the entire calculator code
Any help is appreciated.
It's hard to understand what you expect to happen. For example, look at this code:
#Widgets
if choice == 0:
welcome = Label(app, text="Select a choice")
elif choice == 2:
welcome.config(text="Subtraction")
This code will only ever execute once, and choice will always be zero since that's what you initialize it to. It executes once because it's not in a function and not in a loop, so as python parses the code it will run it and move to the next line. That block of text will never be processed a second time.
If you want the label to change when the user selects a menu item, you'll need to execute that code inside the choice2 function:
def choice2():
global choice
choice = 2
welcome.config(text="Subtraction")

Categories