AttributeError in Tkinter while working with control variables in radiobuttons - python

I'm trying to get the value of the radiobutton selcted and storing this int into a varable. It's my first tkinter project, so I'm sorry for my probably stupid mistakes...
from tkinter import *
from tkinter import ttk
select = "A"
def begin():
grand = Tk()
grand.title("Converter")
window.destroy()
frame = Frame(grand)
option = IntVar()
-> AttributeError: 'NoneType' object has no attribute '_root'
grandlabel = Label(frame, text="Choose the grand").grid(row=0, sticky=N, padx=5)
grand1 = Radiobutton(frame, text="Speed", variable=option, value=1, command=sel).grid(row=1, sticky=W)
grand2 = Radiobutton(frame, text="etc", variable=option, value=2, command=sel).grid(row=2, sticky=W)
submitgrand = Button(frame, text="Ok", command=unit).grid(row=3, sticky=W)
frame.pack()
grand.mainloop()
def sel():
global option
global select
select = option.get()
option = StringVar()
def unit():
unit = Tk()
global select
select = grandchosen
if (grandchosen == "Speed"):
Label(unit, text="Test").pack()
else:
Label(unit, text="Test2").pack()
unit.mainloop()
root = Tk()
frame = Frame(root)
welcome = ttk.Label(frame, text="Welcome!").grid(row=0, sticky=N, padx=10, pady=3)
okbutton = Button(frame, text="Ok", width=15, command=begin).grid(row=1, sticky=S, padx=20, pady=30)
frame.pack()
style = ttk.Style()
style.configure("TLabel", foreground="midnight blue", font="Times 19")
root.mainloop()
Would be great to get some help, thank you!

Related

Python tkinter : how to resize widgets when i resize the screen

I'm beginner...
When the code below is executed, how do I make the widgets inside increase when the screen size is increased to width? but, it couldn't resized..
Does it matter if I use either pack or grid?
i can't solve it....
from tkinter import *
from tkinter import ttk
class program:
def __init__(self):
self.root = Tk()
self.root.title("Python")
self.root.resizable(True, True)
self.create_project()
def create_project(self):
Topic_Label = ttk.Label(self.root, text="program")
Topic_Label.pack(side="top")
Record_LabelFrame = LabelFrame(self.root, text="Record information")
Record_LabelFrame.pack(side="top", anchor=W, padx=10)
date = ttk.Label(Record_LabelFrame, text="date")
date.grid(column=0, row=0, sticky=W)
Topic_Label_Entry1 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry1.grid(column=0, row=1)
time = ttk.Label(Record_LabelFrame, text="time")
time.grid(column=1, row=0, sticky=W)
Topic_Label_Combo1 = ttk.Combobox(Record_LabelFrame)
Topic_Label_Combo1.grid(column=1, row=1)
recorder = ttk.Label(Record_LabelFrame, text="record")
recorder.grid(column=2, row=0, sticky=W)
Topic_Label_Entry2 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry2.grid(column=2, row=1)
loc = ttk.Label(Record_LabelFrame, text="location")
loc.grid(column=0, row=2, sticky="W")
RadioVar = IntVar()
Radio_Frame = Frame(Record_LabelFrame)
Radio_Frame.grid(column=0, row=3, sticky=W)
Topic_Label_Radio1 = ttk.Radiobutton(Radio_Frame, text="A", variable=RadioVar, value=1)
Topic_Label_Radio1.grid(column=0, row=0)
Topic_Label_Radio2 = ttk.Radiobutton(Radio_Frame, text="B", variable=RadioVar, value=2)
Topic_Label_Radio2.grid(column=1, row=0)
Topic_Label_Radio3 = ttk.Radiobutton(Radio_Frame, text="C", variable=RadioVar, value=3)
Topic_Label_Radio3.grid(column=2, row=0)
count = ttk.Label(Record_LabelFrame, text="count")
count.grid(column=1, row=2, sticky="W")
Topic_Label_Combo2 = ttk.Combobox(Record_LabelFrame)
Topic_Label_Combo2.grid(column=1, row=3)
seed_name = ttk.Label(Record_LabelFrame, text="seed")
seed_name.grid(column=2, row=2, sticky="W")
Topic_Label_Entry4 = ttk.Entry(Record_LabelFrame)
Topic_Label_Entry4.grid(column=2, row=3)
mt = program()
mt.root.mainloop()
I want to print like this that widget resize automatically when i resize the screen
https://i.stack.imgur.com/iSbaJ.png
https://i.stack.imgur.com/mzv9R.png

Python progress bar selecting limitation

I'm using Tkinter with a progress bar.
I've got the code below with the "callback" function that adding 50% to my progress bar.
I would like to limit the function to work only once for each OptionMenu selection.
Currently, I can click twice on the first OptionMenu and get to 100% in the progress bar.
Does anyone know what I should change in the "callback" function in order to make it work only once for each OptionMenu? No matter how many times the user has clicked to change its selected value.
from tkinter import *
from tkinter.ttk import Progressbar
root = Tk()
root.title('Input window V1')
root.geometry('600x400')
root.resizable(False, False)
frame = Frame(root, width=600, height=400)
frame.configure(background="gray28")
frame.pack(fill=BOTH, expand=True)
progress = Progressbar(root, orient=HORIZONTAL, length=300, mode='determinate')
progress.place(x=150, y=15)
Budget = {'Flexible', 'Variable', 'Fixed'}
Commitment = {'High', 'Medium', 'Low'}
def callback(*args):
progress["value"] += 50
bottom_header = Label(root, bg="gray28", fg="white", pady=3,
font=("Helvetica", 20, 'underline'), text='Please fill the following attributes:')
bottom_header.place(x=110, y=100)
lbl1 = Label(root, bg="gray28", text='Budget:', fg="cyan2", font=("Helvetica", 14))
lbl1.place(x=120, y=200)
lbl2 = Label(root, bg="gray28", text='Commitment:', fg="cyan2", font=("Helvetica", 14))
lbl2.place(x=120, y=240)
var1 = StringVar(root)
pl1 = OptionMenu(root, var1, *Budget)
pl1.config(width=20, bg="GREEN", fg="white")
pl1.place(x=250, y=200)
var1.trace("w", callback)
var2 = StringVar(root)
pl2 = OptionMenu(root, var2, *Commitment)
pl2.config(width=20, bg="GREEN", fg="white")
pl2.place(x=250, y=240)
var2.trace("w", callback)
global var_dict
var_dict = dict(Budget=var1,
Commitment=var2)
button1 = Button(root, text="Test")
button1.config(width=25, bg="white")
button1.place(x=220, y=320)
root.mainloop()
Thanks in advance!
Try this out:
from tkinter import *
from tkinter.ttk import Progressbar
def callback(*args):
user_input = (var_1.get(), var_2.get()) # Here you can add even more variables
value = 100 - 100/len(user_input)*(user_input.count("")+user_input.count("Select option"))
progress.config(value=value)
root = Tk()
progress = Progressbar(root, orient="horizontal", length=300)
progress.pack()
var_1 = StringVar(root)
var_1.trace("w", callback)
optionmenu_1 = OptionMenu(root, var_1, "Select option", "Option 1", "Option 2")
optionmenu_1.pack()
var_2 = StringVar(root)
var_2.trace("w", callback)
optionmenu_2 = OptionMenu(root, var_2, "Select option", "Option 1", "Option 2")
optionmenu_2.pack()
# You can remove these if you don't like them:
var_1.set("Select option")
var_2.set("Select option")
root.mainloop()
It counts the number of empty OptionMenus and setts the progress bar to the correct percentage.
Keep track of which of the two you have already accounted for, and update only if there was not yet 50% added for this part.
The callback function is changed (and is understandable) and the passing of the callback is changed to a lambda function (which can be confusing if you never used them).
this works for me:
from tkinter import *
from tkinter.ttk import Progressbar
root = Tk()
root.title('Input window V1')
root.geometry('600x400')
root.resizable(False, False)
frame = Frame(root, width=600, height=400)
frame.configure(background="gray28")
frame.pack(fill=BOTH, expand=True)
progress = Progressbar(root, orient=HORIZONTAL, length=300, mode='determinate')
progress.place(x=150, y=15)
Budget = {'Flexible', 'Variable', 'Fixed'}
Commitment = {'High', 'Medium', 'Low'}
budgetset = False
commitmentset = False
def callback(nb):
global budgetset, commitmentset
if nb == 0 and not budgetset:
budgetset = True
progress["value"] += 50
if nb == 1 and not commitmentset:
commitmentset = True
progress["value"] += 50
bottom_header = Label(root, bg="gray28", fg="white", pady=3,
font=("Helvetica", 20, 'underline'), text='Please fill the following attributes:')
bottom_header.place(x=110, y=100)
lbl1 = Label(root, bg="gray28", text='Budget:', fg="cyan2", font=("Helvetica", 14))
lbl1.place(x=120, y=200)
lbl2 = Label(root, bg="gray28", text='Commitment:', fg="cyan2", font=("Helvetica", 14))
lbl2.place(x=120, y=240)
var1 = StringVar(root)
pl1 = OptionMenu(root, var1, *Budget)
pl1.config(width=20, bg="GREEN", fg="white")
pl1.place(x=250, y=200)
var1.trace("w", lambda *_, x=0: callback(x))
var2 = StringVar(root)
pl2 = OptionMenu(root, var2, *Commitment)
pl2.config(width=20, bg="GREEN", fg="white")
pl2.place(x=250, y=240)
var2.trace("w", lambda *_, x=1: callback(x))
global var_dict
var_dict = dict(Budget=var1,
Commitment=var2)
button1 = Button(root, text="Test")
button1.config(width=25, bg="white")
button1.place(x=220, y=320)
root.mainloop()

Parameters passed to a function does not works as intended

When the "view" button is pressed, it should trigger the function solution(i) such that label should be displayed in the new window. The problem is that the window opens and the previous label is packed but the label which gets it's text from "i" does not gets packed, Is there any issue in passing the parameter.
Any help is appreciated.
root = Tk()
root.config(background = "#303939")
root.state('zoomed')
def pre():
with open("DoubtSolution.txt","r+") as f:
dousol = f.read()
dousol_lst = dousol.split("`")
k = 0
window = Tk()
window.config(background = "#303939")
window.state('zoomed')
predoubt = Label(window,
text="Previous Doubts",
fg="Cyan",
bg="#303939",
font="Helvetica 50 bold"
).grid(row=0, column=1)
def solution(text):
print(text)
window1 = Tk()
window1.config(background="#303939")
window1.state('zoomed')
sol = Label(window1,
text=text[:text.find("~")],
font=font.Font(size=20),
bg="#303939",
fg="Cyan")
sol.pack()
window1.mainloop()
for i in dousol_lst:
if i[-5:] == admno:
doubt = Label(window, text=i[i.find("]]")+2:i.find("}}}}")], font=font.Font(size=20), bg="#303939",
fg="Cyan")
doubt.grid(row=2+k, column=1, pady=10)
view = Button(
master=window,
text="View", font=font.Font(size=15, family="Helvetica"),
activebackground="White",
bg="Teal",
bd=0.8,
fg="White",
command = lambda k = k:solution(i)
)
view.grid(row=2+k, column=2, padx=20)
k=k+1
window.mainloop()
previous = Button(
master=root,
text="Previous Doubts", font="Helvetica 22 bold",
activebackground="White",
bg="Teal",
bd=0.8,
fg="White",
command = pre
).grid(row=4, column=3, padx=20)
root.mainloop()

Button Adjusting tkinter Python 3.8

all of my code is ready except the placement of the Quit button. I want to move to the Calculate button as much as possible, even like sticked to each other. Could you help in adjusting so the buttons will stick to each other?
from tkinter import *
window = Tk()
class MainGUI:
def __init__(self):
Label(window, text="Enter the property value: $").grid(row=1,column=1, sticky=W)
Label(window, text="Assessment Value").grid(row=2,column=1, sticky=W)
Label(window, text="Property Tax").grid(row=3,column=1, sticky=W)
self.propertyValue = StringVar()
self.assessmentValue = StringVar()
self.propertyTax = StringVar()
Entry(window, textvariable=self.propertyValue,justify=RIGHT).grid(row=1, column=2)
Button(window, text="Calculate",
command=self.calculate).grid(row=6, column=1, sticky=E)
Button(window, text="Quit",
command=self.close_window).grid(row=6, column=2, sticky=E)
Label(window, textvariable=
self.assessmentValue).grid(row=2, column=2, sticky=E)
Label(window, textvariable=
self.propertyTax).grid(row=3, column=2, sticky=E)
window.mainloop() # Create an event loop
def calculate(self):
self.assessmentValue.set("{0:10.2f}".format(float(self.propertyValue.get()) * 60 / 100))
self.propertyTax.set("{0:10.2f}".format(float(self.propertyValue.get()) * 60 / 10000 * 0.75))
def close_window(self):
window.destroy()
MainGUI()

python tkinter combobox/button

I just started to use python and tkinter, I have created a gui with two combobox and 'run' buttons which contain two different options 'SPMI' and 'RFFE'. What I want my script to do is, when I select different options and click 'run' it should run the SPMI.py or RFFE.py file.
Help please, Thanks
My code:
import sys
from Tkinter import *
def callback1():
os.system('SPMI.py')
def callback2():
os.system('RFFE.py')
class MyOptionMenu(OptionMenu):
def __init__(self, master, status, *options):
self.var = StringVar(master)
self.var.set(status)
OptionMenu.__init__(self, master, self.var, *options)
self.config(font=('calibri',(10)),bg='white',width=12,fg='dark red')
self['menu'].config(font=('calibri',(10)),bg='white',fg='dark blue')
b1_1 = Button(Dragonfly, text = "Run", fg='blue',command=callback1)
b1_1.place(x=85,y=150)
b2_2= Button(Dragonfly, text = "Run", fg='blue',command=callback2)
b2_2.place(x=275,y=150)
Dragonfly = Tk()
Dragonfly.geometry('400x400+400+300')
Dragonfly.title('Dragonfly')
mainlabel = Label(text='Dragonfly Trigger Test',font=('calibri',(14)),fg='dark blue').pack()
mymenu1 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI','RFFE')
mymenu2 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI','RFFE')
mymenu1.place(x=40,y=100)
mymenu2.place(x=230,y=100)
m1label = Label(text='Frame Trigger',font=('calibri',(12)),fg='dark green').place(x=57,y=60)
m1labe2 = Label(text='External Trigger',font=('calibri',(12)),fg='dark green').place(x=240,y=60)
Dragonfly.mainloop()
Use self.var.get() to get the value of the combobox.
You can then use that value inside the callback to make the callback's behavior depend on the combobox's setting.
import sys
from Tkinter import *
import subprocess
class MyOptionMenu(OptionMenu):
def __init__(self, master, status, *options):
self.var = StringVar(master)
self.var.set(status)
OptionMenu.__init__(self, master, self.var, *options)
self.config(
font=('calibri', (10)), bg='white', width=12, fg='dark red')
self['menu'].config(font=('calibri', (10)), bg='white', fg='dark blue')
def callback(self):
val = '{}.py'.format(self.var.get())
print(val)
# subprocess.call([val])
Dragonfly = Tk()
Dragonfly.geometry('400x400+400+300')
Dragonfly.title('Dragonfly')
mainlabel = Label(text='Dragonfly Trigger Test', font=('calibri', (14)),
fg='dark blue').pack()
mymenu1 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI', 'RFFE')
b1_1 = Button(Dragonfly, text="Run", fg='blue', command=mymenu1.callback)
b1_1.place(x=85, y=150)
mymenu2 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI', 'RFFE')
b2_2 = Button(Dragonfly, text="Run", fg='blue', command=mymenu2.callback)
b2_2.place(x=275, y=150)
mymenu1.place(x=40, y=100)
mymenu2.place(x=230, y=100)
m1label = Label(text='Frame Trigger', font=('calibri', (12)),
fg='dark green').place(x=57, y=60)
m1labe2 = Label(text='External Trigger', font=('calibri', (12)),
fg='dark green').place(x=240, y=60)
Dragonfly.mainloop()
By the way, building a GUI with place is easy at first, but cumbersome in the end. For one thing, as it grows it become harder and harder to change the layout since inserting a new widget will tend to require fiddling with hard-coded coordinates all over the place. Another problem is that the widget layout fails to adjust to changes in window size.
For those reasons, people tend to use pack or grid to layout widgets:
import sys
import Tkinter as tk
import subprocess
class MyOptionMenu(tk.OptionMenu):
def __init__(self, master, status, *options):
self.var = tk.StringVar(master)
self.var.set(status)
tk.OptionMenu.__init__(self, master, self.var, *options)
self.config(
font=('calibri', (10)), bg='white', width=12, fg='dark red')
self['menu'].config(font=('calibri', (10)), bg='white', fg='dark blue')
def callback(self):
val = '{}.py'.format(self.var.get())
print(val)
# subprocess.call([val])
Dragonfly = tk.Tk()
Dragonfly.geometry('400x400+400+300')
Dragonfly.title('Dragonfly')
Dragonfly.columnconfigure(0, weight=1)
Dragonfly.columnconfigure(1, weight=1)
mainlabel = tk.Label(text='Dragonfly Trigger Test', font=('calibri', (14)),
fg='dark blue').grid(row=0, column=0, columnspan=2, pady=20)
mymenu1 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI', 'RFFE')
mymenu1.grid(row=2, column=0, pady=10, padx=10,)
b1_1 = tk.Button(Dragonfly, text="Run", fg='blue', command=mymenu1.callback)
b1_1.grid(row=3, column=0, pady=10, padx=10,)
mymenu2 = MyOptionMenu(Dragonfly, 'Select Protocol', 'SPMI', 'RFFE')
mymenu2.grid(row=2, column=1, pady=10, padx=10,)
b2_2 = tk.Button(Dragonfly, text="Run", fg='blue', command=mymenu2.callback)
b2_2.grid(row=3, column=1, pady=10, padx=10,)
m1label = tk.Label(text='Frame Trigger', font=('calibri', (12)),
fg='dark green').grid(row=1, column=0, pady=10, padx=10,)
m1labe2 = tk.Label(text='External Trigger', font=('calibri', (12)),
fg='dark green').grid(row=1, column=1, pady=10, padx=10,)
Dragonfly.mainloop()

Categories