problem with tkinter under defined function - python

Can you please help me with follwing issue I face:
When I am creating radiobutton with tkinter, I don't have a problem to select from the list.
However, if I put the same script under a menu, then selected option is always the default one, ("Python",1) in this specific case. Do you have any idea how to overcome this? Thanks in advance!
import tkinter as tk
root_m = tk.Tk()
root_m.geometry("400x200")
frame_m = tk.Frame(root_m)
root_m.title("NUMERIC UNIVERSE")
frame_m.pack()
def chars_merging():
languages = [
("Python",1),
("Perl",2),
("Java",3),
("C++",4),
("C",5)
]
root = tk.Tk()
root.geometry("400x200")
frame = tk.Frame(root)
root.title("SELECT SOMETHING")
frame.pack()
v = tk.IntVar()
v.set(0) # initializing the choice, i.e. Python
label = tk.Label(frame,
text="""Choose your favourite
programming language:""",
justify = tk.LEFT,
padx = 20)
label.pack()
def ShowChoice():
global data_sel
data_sel = v.get()
print(data_sel)
for val, language in enumerate(languages):
tk.Radiobutton(frame,
text=language,
indicatoron = 0,
width = 20,
padx = 20,
variable=data_sel,
command=ShowChoice,
value=val).pack(anchor=tk.W)
root.mainloop()
#return(languages[v.get()])
print("You selected", languages[v.get()])
button3 = tk.Button(frame_m,
text="3.Prepare and merge chars",
command=chars_merging,
width=25)
button3.pack()
# CLOSING THE WINDOW ---------------------------------------------------------
def finish():
root_m.destroy()
button_n = tk.Button(frame_m,
text="Finish",
command=finish,
width=25)
button_n.pack()
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
root_m.mainloop()

Related

Newbie problem with using tkinter checkbutton in a class

Running python 3.8 in PyCharm
I'm trying to create a class to allow creation of a tkinter checkbutton (and eventually other widgets) that will hold all the formatting and definition for the widget. I would like to be able to test the state of the checkbutton and act on it in a callback. But like many others, my checkbutton variable seems to always be 0. I'm fairly sure its a garbage collection issue, but I can't figure a way around it. Note the second set of parameters in the class definition specify the location of the label to display the checkbutton variable state. At the moment, the callback is just to display the variable state in a label.
Acknowledgement:
I modified code from Burhard Meier's book "Python GUI Programming Cookbook" for this. The code related to the class is mine, the rest is from Burkhard Meier.
'''
This is a modification of code by Burhard A. Meier
in "Python GUI Programming Cookbook"
Created on Apr 30, 2019
#author: Burkhard A. Meier
'''
#======================
# imports
#======================
import tkinter as tk
from tkinter import ttk
# Create instance
win = tk.Tk()
# Add a title
win.title("GUI Test Box")
# Modify adding a Label
a_label = ttk.Label(win, text="Testing TK Widgets")
a_label.grid(column=0, row=0)
# Modified Button Click Function
def click_me():
action.configure(text='Hello ' + name.get() + ' ' +
number_chosen.get())
#Define the Checkbutton Class
class ChkBut(): #lable, xloc, yloc, xlab, ylab
def __init__(self, lable, xloc, yloc, xlab, ylab): # , xloc, yloc, text="default", variable = v, onvalue='Set', offvalue='NotSet'):
v = tk.IntVar()
self.v = v
self.lable = lable
self.xloc = xloc
self.yloc = yloc
self.xlab = xlab
self.ylab = ylab
c = tk.Checkbutton(
win,
text= self.lable,
variable=self.v,
command=self.cb(self.v, xlab,ylab))
c.grid(column=xloc, row=yloc, sticky = tk.W)
c.deselect()
def cb (self, c, xlab, ylab):
if c.get()==1:
c_label = ttk.Label(win, text="Set")
c_label.grid(column=xlab, row=ylab)
elif c.get()==0:
c_label = ttk.Label(win, text="NotSet")
c_label.grid(column=xlab, row=ylab)
else:
c_label = ttk.Label(win, text=c.v.get())
c_label.grid(column=xlab, row=ylab)
# Changing the Label
ttk.Label(win, text="Enter a name:").grid(column=0, row=0)
# Adding a Textbox Entry widget
name = tk.StringVar()
name_entered = ttk.Entry(win, width=12, textvariable=name)
name_entered.grid(column=0, row=1)
# Adding a Button
action = ttk.Button(win, text="Click Me!", command=click_me)
action.grid(column=2, row=1)
# Creating three checkbuttons
ttk.Label(win, text="Choose a number:").grid(column=1, row=0)
number = tk.StringVar()
number_chosen = ttk.Combobox(win, width=12, textvariable=number, state='readonly')
number_chosen['values'] = (1, 2, 4, 42, 100)
number_chosen.grid(column=1, row=1)
number_chosen.current(0)
check1 = ChkBut("Button 1", 0, 4, 0, 5)
chVarUn = tk.IntVar()
check2 = tk.Checkbutton(win, text="UnChecked", variable=chVarUn)
check2.deselect()
check2.chVarUn = 0
check2.grid(column=1, row=4, sticky=tk.W)
chVarEn = tk.IntVar()
check3 = tk.Checkbutton(win, text="Enabled", variable=chVarEn)
check3.select()
check3.chVarEn = 0
check3.grid(column=2, row=4, sticky=tk.W)
name_entered.focus() # Place cursor into name Entry
#======================
# Start GUI
#======================
win.mainloop()

Graphic InterfaceTkinter Python

I´m having a problem with my interface using Tkinter in Python. I would like to put the phrase "Primeira cesta" and the button "Aplicar", at the top of the interface, not at the bottom. After that, I would like that comes the dropdown.
Can anybody help me, please?
Code
from tkinter import*
class Application():
def init(self, master):
mainframe = Frame(root)
mainframe.grid(column=0, row=0,sticky=(N,W,E,S))
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
mainframe.pack(pady = 100, padx = 100)
#color1
self.widget1 = Frame(master)
self.widget1.pack(side=TOP)
self.msg = Label(self.widget1, text="Primeira cesta")
self.msg["font"]=("Times New Roman", "12", "italic", "bold")
self.msg.pack()
self.aplicar=Button(self.widget1)
self.aplicar["text"]="Aplicar"
self.aplicar["font"]=("Calibri","10")
self.aplicar["width"]=5
self.aplicar["command"]=self.mudarTexto
self.aplicar.pack()
#Dropdown1
# Create a Tkinter variable
tkvar = StringVar(root)
tkvar2 = StringVar(root)
# Dictionary with options
cores = { 'Amarelo','Azul','Verde','Vermelho'}
formatos = {'2x1','2x2','2x3','2x4'}
tkvar.set('Cores') # set the default option
tkvar2.set('Formatos')
popupMenu = OptionMenu(mainframe, tkvar, *cores)
label1=Label(mainframe, text="Escolha uma cor")
label1.grid(row=1, column=1)
popupMenu.grid(row = 2, column =1)
popupMenu2 = OptionMenu(mainframe, tkvar2, *formatos)
label2=Label(mainframe, text="Escolha um formato")
label2.grid(row=3,column=1)
popupMenu2.grid(row = 4, column =1)
# on change dropdown value
def change_dropdown(*args):
print( tkvar.get() )
def change_dropdown2(*args):
print( tkvar2.get() )
# link function to change dropdown
tkvar.trace('w', change_dropdown)
tkvar2.trace('w', change_dropdown2)
def mudarTexto(self):
if self.msg["text"]=="Primeira cesta":
self.msg["text"]="A primeira cesta foi configurada"
else:
self.msg["text"]="Primeira cesta"
root=Tk()
Application(root)
root.mainloop()
enter image description here

Switch between multiple frames using tkinter in python in side menubar

I am trying to create a side menubar and use multiple labels as click buttons. But when I execute the program, only one label is clicked and event is shown in mainarea. Other event doesn't work.
Please provide me with a useful solution. Here is the code I have written:
from Tkinter import *
import ttk
root = Tk()
def MainScreen(self):
label4 = Label(mainarea,width=100,height=80,text="Prapti Computer
Solutions")
label4.pack(expand=True,fill='both')
def ClientData(self):
label4 = Label(mainarea,width=100,height=80,text="Yo this is client data")
label4.pack(expand=True,fill='both')
def Report(self):
label6 = Label(mainarea,width=100,height=80,text="Report is onnnnn!")
label6.pack(expand=True,fill='both')
# sidebar
sidebar = Frame(root, width=400, bg='white', height=500, borderwidth=2)
sidebar.pack( fill='y', side='left', anchor='nw')
#submenus
label1 = Label( sidebar,width=45,height = 2 , text="HOME", relief=FLAT )
label1.bind("<Button-1>",MainScreen)
label1.grid(row=0)
ttk.Separator(sidebar,orient=HORIZONTAL).grid(row=1, columnspan=5)
label2 = Label( sidebar,width=45,height = 2 , text="CLIENT", relief=FLAT )
label2.bind("<Button-1>",ClientData)
label2.grid(row=2)
ttk.Separator(sidebar,orient=HORIZONTAL).grid(row=3, columnspan=5)
label3 = Label( sidebar,width=45,height = 2 , text="REPORT", relief=FLAT )
label3.bind("<Button-1>",Report)
label3.grid(row=4)
# main content area
mainarea = Frame(root, bg='#CCC', width=500, height=500)
mainarea.pack(expand=True, fill='both', side='right')
root.attributes('-alpha', 0.98)
root.mainloop()
Thank you.
You keep packing things but you never remove them. You need to remove the current page before switching to the new page.
For example:
current_page = None
def MainScreen(self):
global current_page
if current_page is not None:
current_page.pack_forget()
label4 = Label(mainarea,width=100,height=80,text="Prapti Computer Solutions")
label4.pack(expand=True,fill='both')
current_page = label4

Python/Tkinter: How to reduce the size of the expanded frames to their first positions?

According to the below codes; when the application is first run, two buttons display on the screen. If the user click one of the buttons, the frame is expanded and new buttons can be seen. If the user click the new buttons, another frame is expanded and new buttons can be seen again.
For example if the user first clicks the "English" button, the "Expand" button can be seen. And if the user click the "Expand" button, "Data" button can be seen. After that if the user click the "Turkish" button, the "Expand" button changes to "Genişlet" but the "Data" button still keeps on displaying, finally if the user clicks the "Genişlet" button, the "Data" button changes to "Veri".
But the above operation is not what i want to do. I want to change the "Veri" or "Data" buttons by clicking the "English" or "Turkish" buttons.
So, in order to do that, which parts of the codes i should modify? Thank you in advance.
import tkinter as tk
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid(row=0, column=0, sticky="nsew")
self.b1 = tk.Button(master=self, text="Turkish", width=20)
self.b1.grid(row=0, column=0)
self.b2 = tk.Button(master=self, text="English", width=20)
self.b2.grid(row=0, column=1)
self.f1 = tk.Frame(master=master)
self.f1.grid(row=1, column=0)
self.f2 = tk.Frame(master=master)
self.f2.grid(row=2, column=0)
self.f3 = tk.Frame(master=self.f1)
self.f4 = tk.Frame(master=self.f1)
self.b3 = tk.Button(master=self.f3, text="Genişlet")
self.b3.grid(row=0, column=0)
self.b4 = tk.Button(master=self.f4, text="Expand")
self.b4.grid(row=0, column=0)
self.f5 = tk.Frame(master=self.f2)
self.f6 = tk.Frame(master=self.f2)
self.b5 = tk.Button(master=self.f5, text="Veri")
self.b5.grid(row=0, column=0)
self.b6 = tk.Button(master=self.f6, text="Data")
self.b6.grid(row=0, column=0)
self.configure_buttons()
#staticmethod
def activate(frame, parent):
for child in parent:
child.grid_forget()
frame.grid(row=0, column=0)
def configure_buttons(self):
self.b1.configure(command=lambda: self.activate(self.f3, self.f1.winfo_children()))
self.b2.configure(command=lambda: self.activate(self.f4, self.f1.winfo_children()))
self.b3.configure(command=lambda: self.activate(self.f5, self.f2.winfo_children()))
self.b4.configure(command=lambda: self.activate(self.f6, self.f2.winfo_children()))
if __name__ == "__main__":
root = tk.Tk()
frame = App(master=root)
frame.mainloop()
Here is an example that keeps the functionality you currently have while being able to apply the language changes using textvariable and stringVar()
There is a better way I am sure but for this simple program this should suffice.
I created two variables set to a StringVar() The first 2 buttons are linked to a function/method that will change the strings for each stringVar to reflect the language choice.
I also created some place holder variables to use until the other buttons needed to be created. Let me know what you think of this option.
Update: I added a menu that will remove all the buttons except for the starting 2 buttons. Effectively a restart.
import tkinter as tk
class App(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.master = master
self.btn1_text = tk.StringVar()
self.btn1_text.set("Expand")
self.btn2_text = tk.StringVar()
self.btn2_text.set("Data")
self.second_frame = "None"
self.btn2 = "None"
self.master.columnconfigure(0, weight = 1)
self.top_frame = tk.Frame(self.master)
self.top_frame.grid(row = 0, column = 0, sticky = "ew")
self.turkish_button = tk.Button(self.top_frame, text="Turkish", width=20, command = lambda: self.change_lang_and_add_btn1("turkish"))
self.turkish_button.grid(row=0, column=0)
self.english_button = tk.Button(self.top_frame, text="English", width=20, command = lambda: self.change_lang_and_add_btn1("english"))
self.english_button.grid(row=0, column=1)
self.menu = tk.Menu(self.master)
self.master.config(menu = self.menu)
self.file_menu = tk.Menu(self.menu, tearoff = 0)
self.menu.add_cascade(label = "File", menu = self.file_menu)
self.file_menu.add_command(label = "Reset", command = self.reset_buttons)
def change_lang_and_add_btn1(self, choice):
if choice == "english":
self.btn1_text.set("Expand")
self.btn2_text.set("Data")
if choice == "turkish":
self.btn1_text.set("Genişlet")
self.btn2_text.set("Veri")
if self.second_frame == "None":
self.second_frame = tk.Frame(self.master)
self.second_frame.grid(row = 1, column = 0, columnspan = 2)
self.btn1 = tk.Button(self.second_frame, textvariable = self.btn1_text, width=20, command = lambda: self.add_btn2())
self.btn1.grid(row = 1, column = 0, columnspan = 2)
def add_btn2(self):
if self.btn2 == "None":
self.btn2 = tk.Button(self.second_frame, textvariable = self.btn2_text, width=20)
self.btn2.grid(row = 2, column = 0, columnspan = 2)
def reset_buttons(self):
if self.second_frame != "None":
self.second_frame.destroy()
self.second_frame = "None"
self.btn2 = "None"
if __name__ == "__main__":
root = tk.Tk()
frame = App(root)
frame.mainloop()

How to store values from an Entry widget for loop in tkinter?

This should be a very very simple problem. I'm making a GUI in which I have multiple entry widgets... about 30 or so all in one column. Instead of making each box one by one it seems like a better idea to just generate the widgets with a loop. However, I'm finding it extremely difficult to .get() values from the entry widgets, and convert them into floats. This is what I have so far... any help would be greatly appreciated.
class Application(Frame):
def __init__(root,master):
Frame.__init__(root,master)
root.grid()
root.create_widgets()
def calcCR(root):
d1 = root.enter.get()
d1 = float(d1)
#root.answer.delete(0.0,END)
a = 'The C/R Alpha is! %lf \n' % (d1)
root.answer.insert(0.0, a)
def create_widgets(root):
### Generate Element List ###
for i in range(len(elem)):
Label(root, text=elem[i]).grid(row=i+1, column=0)
### Generate entry boxes for element wt% ###
for i in range(len(elem)):
enter = Entry(root, width = 8)
enter.grid(row = i+1,column=1)
enter.insert(0,'0.00')
root.button = Button(root, text = 'Calculate C/R', command = root.calcCR)
root.button.grid(row=11, column=2, sticky = W, padx = 10)
root.answer = Text(root, width = 50, height = 12.5, wrap = WORD)
root.answer.grid(row=1, column=2, rowspan = 10, sticky = W, padx = 10)
root = Tk()
root.title('C/R Calculator')
app = Application(root)
root.mainloop()
Put the Entry instances into a list.
from tkinter import Tk, Frame, Label, Entry, Button
class App(Frame):
def __init__(root, master):
Frame.__init__(root, master)
root.grid()
root.create_widgets()
def get_values(root):
return [float(entry.get()) for entry in root.entries]
def calc_CR(root):
answer = sum(root.get_values()) #Replace with your own calculations
root.answer.config(text=str(answer))
def create_widgets(root):
root.entries = []
for i in range(20):
label = Label(root, text=str(i))
label.grid(row=i, column=0)
entry = Entry(root, width=8)
entry.grid(row=i, column=1)
entry.insert(0, '0.00')
root.entries.append(entry)
root.calc_button = Button(root, text='Calculate C/R', command=root.calc_CR)
root.calc_button.grid(row=20, column=0)
root.answer = Label(root, text='0')
root.answer.grid(row=20, column=1)
def run(root):
root.mainloop()
root = Tk()
root.title('C/R Calculator')
app = App(root)
app.run()

Categories