Related
I'm trying to make a small tkinter program to calculate the area of shapes and volumes
and I've made a main py file "area_volume_calculator.py" and two libraries "area.py" and "volume.py"
The main program's radio buttons work fine, but when I create the second window from Area_calculator I can't seem to get radio buttons to work properly. When it opens, the last 2 radio buttons are selected already.
I can still select an option but self.choice.get() always returns the default value which is -1, I don't know how to get it to work.
Can anyone help me get the radio buttons to work properly?
Any and all help is appreciated
Main Program:
from tkinter import *
from area import *
# from volume import *
class Menu:
def __init__(self):
self.window = Tk()
self.window.title("Areas and Volumes")
# self.name_label = Label(self.window, text = "Name: ")
# self.name_label.grid(row=0,column=0)
# self.name_entry = Entry(self.window)
# self.name_entry.grid(row=0,column=1)
# self.age_label = Label(self.window, text = "Age: ")
# self.age_label.grid(row=1,column=0)
# self.age_entry = Entry(self.window)
# self.age_entry.grid(row=1,column=1)
self.choice = IntVar()
self.area_radiobutton = Radiobutton(self.window, text = "Area Calculator", var = self.choice, value = 0)
self.area_radiobutton.grid(row=2,column=0)
self.volume_radiobutton = Radiobutton(self.window, text = "Volume Calculator", var = self.choice, value = 1)
self.volume_radiobutton.grid(row=3,column=0)
self.choice.set(-1)
self.submit_button = Button(self.window, text = "Submit", command = self.submit)
self.submit_button.grid(row=4,column=0)
print(self.choice.get())
self.window.mainloop()
def submit(self):
print(self.choice.get())
if self.choice.get() == 0:
area_calculator = Area_calculator()
# elif self.choice.get() == 1:
# volume_calculator = Volume_calculator()
menu = Menu()
area.py library:
from tkinter import *
class Area_calculator():
def __init__(self):
self.window = Tk()
self.window.title
self.window.title("Area Calculator")
self.choice_label = Label(self.window, text = "Choose a shape")
self.choice_label.grid(row=0,columnspan=1)
self.choice = IntVar()
self.rectangle_radiobutton = Radiobutton(self.window, text = "Rectangle", var = self.choice, value = 0)
self.rectangle_radiobutton.grid(row=1,column=0)
self.triangle_radiobutton = Radiobutton(self.window, text = "Triangle", var = self.choice, value = 1)
self.triangle_radiobutton.grid(row=2,column=0)
self.circle_radiobutton = Radiobutton(self.window, text = "Circle", var = self.choice, value = 2)
self.circle_radiobutton.grid(row=3,column=0)
self.submit_button = Button(self.window, text = "Submit", command = self.submit)
self.submit_button.grid(row=4,column=0)
self.choice.set(-1)
print(self.choice.get())
self.window.mainloop()
def submit(self):
print(self.choice.get())
# if self.choice.get() == 0:
# rectangle_calculator = Rectangle_calculator()
# elif self.choice.get() == 1:
# triangle_calculator = Triangle_calculator()
# elif self.choice.get() == 2:
# circle_calculator = Circle_calculator()
You are creating two instances of tk.Tk() (one in each class) which is never a good idea. tk.Tk() does not just create a new window but also a new embedded Tcl interpreter and this can mess things up, particularly IntVars and other variables such as self.choice. For more information see here.
If you want to have multiple windows then use tk.Toplevel() instead.
In answer to your second question in the comments, you must first add the parameters name and age to the __init__ of the Area_calculator class, and also pass them to the class when creating it in Menu.
Completed code:
Main program:
from tkinter import *
from area import *
class Menu:
def __init__(self):
self.window = Tk()
self.window.title("Areas and Volumes")
self.name_label = Label(self.window, text = "Name: ")
self.name_label.grid(row=0,column=0)
self.name_entry = Entry(self.window)
self.name_entry.grid(row=0,column=1)
self.age_label = Label(self.window, text = "Age: ")
self.age_label.grid(row=1,column=0)
self.age_entry = Entry(self.window)
self.age_entry.grid(row=1,column=1)
self.choice = IntVar()
self.area_radiobutton = Radiobutton(self.window, text = "Area Calculator", var = self.choice, value = 0)
self.area_radiobutton.grid(row=2,column=0)
self.volume_radiobutton = Radiobutton(self.window, text = "Volume Calculator", var = self.choice, value = 1)
self.volume_radiobutton.grid(row=3,column=0)
self.choice.set(-1)
self.submit_button = Button(self.window, text = "Submit", command = self.submit)
self.submit_button.grid(row=4,column=0)
print(self.choice.get())
self.window.mainloop()
def submit(self):
print(self.choice.get())
if self.choice.get() == 0:
name = self.name_entry.get()
age = self.age_entry.get()
area_calculator = Area_calculator(name, age)
menu = Menu()
area.py library:
from tkinter import *
class Area_calculator():
def __init__(self, name, age):
self.window = Toplevel()
self.window.title
self.window.title("Area Calculator")
self.name_label = Label(self.window, text = f"{name=}", width=10)
self.name_label.grid()
self.age_label = Label(self.window, text = f"{age=}", width=10)
self.age_label.grid(row=0, column=1)
self.choice_label = Label(self.window, text = "Choose a shape")
self.choice_label.grid(row=1,columnspan=1)
self.choice = IntVar()
self.rectangle_radiobutton = Radiobutton(self.window, text = "Rectangle", var = self.choice, value = 0)
self.rectangle_radiobutton.grid(row=2,column=0)
self.triangle_radiobutton = Radiobutton(self.window, text = "Triangle", var = self.choice, value = 1)
self.triangle_radiobutton.grid(row=3,column=0)
self.circle_radiobutton = Radiobutton(self.window, text = "Circle", var = self.choice, value = 2)
self.circle_radiobutton.grid(row=4,column=0)
self.submit_button = Button(self.window, text = "Submit", command = self.submit)
self.submit_button.grid(row=5,column=0)
self.choice.set(-1)
print(self.choice.get())
self.window.mainloop()
def submit(self):
print(self.choice.get())
My first post, so I apologize as I learn to use this. Also, I am sure my code is very jumbled and rudimentary, but I am not here to get someone to re-write my code. I have a question about how a widget is behaving and an error code I am getting.
I currently have two frames in a mainWindow, and when you click a button labeled "New", a small window (newWindow) pops up that has a registration form, and a button labeled "Register" to write the form data to a .txt file.
The problem I am having is that if I do not define where the button should go, it appears in the mainWindow. If I specify for it to appear in the newWindow, it does not appear and throws me the following error:
File
"/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/tkinter/init.py",
line 1507, in nametowidget
w = w.children[n] KeyError: '!button2'
Here is my code (get ready for a mess!):
from tkinter import *
from tkinter import ttk
from time import strftime
from tkmacosx import SFrame, Button
import tkinter as tk
mainWindow = Tk()
mainWindow.title('BATCO Main')
def createWindow():
#When createWindow() is called, the following code is executed, starting with creating the window object itself, which is set to the Tk() widget caller
newWindow = Tk()
# Add title of window
newWindow.title('Patron Entry')
# Set from and geometry of the Button (widthxheight+XPOS+YPOS)
newWindow.geometry('500x350+100+200')
# THIS PART CREATES AND APPENDS THE FILE FOR STORING NAMES:
def saveInfo():
# Defines Variables(3) for the "get" Method that will take from the StringVar Variables(2) above:
fname_info = fname.get()
mname_info = mname.get()
lname_info = lname.get()
suffix_info = suffix.get()
addr1_info = addr1.get()
addr2_info = addr2.get()
city_info = city.get()
state_info = state.get()
zipcode_info = zipcode.get()
print(fname_info, mname_info, lname_info, suffix_info, addr1_info, addr2_info, city_info, state_info, zipcode_info)
# This starts by opening the file 'patrons.txt' and assigns it to the file Variable. It uses the Arg 'a' which stands for Append, so it will add to the file.
file = open('patrons.txt', 'a')
# Once the file is open, write to it using the write method on the Variable file. The Write method accepts one Arg, so I have to use the + Operator to Concatenate text.
file.write (fname_info + ',')
file.write (mname_info + ',')
file.write (lname_info + ',')
file.write (suffix_info + ',')
file.write (addr1_info + ',')
file.write (addr2_info + ',')
file.write (city_info + ',')
file.write (state_info + ',')
file.write (zipcode_info + ';\n')
file.close ()
print (fname_info, 'has been registered')
# Clears the fields in the form
fname_entry.delete(0, END)
mname_entry.delete(0, END)
lname_entry.delete(0, END)
suffix_entry.delete(0, END)
addr1_entry.delete(0, END)
addr2_entry.delete(0, END)
city_entry.delete(0, END)
state_entry.delete(0, END)
zipcode_entry.delete(0, END)
# This code closes the window after entry
newWindow.destroy()
# End of saveInfo function
# Creating basic text that is formatted to be a header at the top of the window
lbl = Label(newWindow, text = 'Create Record', bg = 'light gray', fg = 'gray', width = '50', font = ('Arial', 17))
lbl.place(x=0, y=0)
# Defining Variables(1) for the text box labels:
fname_text = Label(newWindow, text = 'First Name', fg = 'gray', font = ('Arial', 12))
mname_text = Label(newWindow, text = 'Middle name', fg = 'gray', font = ('Arial', 12))
lname_text = Label(newWindow, text = 'Last Name', fg = 'gray', font = ('Arial', 12))
suffix_text = Label(newWindow, text = 'Suffix', fg = 'gray', font = ('Arial', 12))
addr1_text = Label(newWindow, text = 'Address 1', fg = 'gray', font = ('Arial', 12))
addr2_text = Label(newWindow, text = 'Address 2', fg = 'gray', font = ('Arial', 12))
city_text = Label(newWindow, text = 'City', fg = 'gray', font = ('Arial', 12))
state_text = Label(newWindow, text = 'State', fg = 'gray', font = ('Arial', 12))
zip_text = Label(newWindow, text = 'Zip', fg = 'gray', font = ('Arial', 12))
# Placing text box labels:
fname_text.place(x = 15, y = 50)
mname_text.place(x = 155, y = 50)
lname_text.place(x = 295, y = 50)
suffix_text.place(x = 435, y = 50)
addr1_text.place(x = 15, y = 100)
addr2_text.place(x = 15, y = 150)
city_text.place(x = 15, y = 200)
state_text.place(x = 318, y = 200)
zip_text.place(x = 367, y = 200)
# Defining and formatting Variables(2) for the data entered INTO the Entry boxes:
fname = StringVar()
mname = StringVar()
lname = StringVar()
suffix = StringVar()
addr1 = StringVar()
addr2 = StringVar()
city = StringVar()
state = StringVar()
zipcode = StringVar()
# Defining the Variables(3) for the Entry boxes:
fname_entry = Entry(newWindow, textvariable = fname, width = 14)
mname_entry = Entry(newWindow, textvariable = mname, width = 14)
lname_entry = Entry(newWindow, textvariable = lname, width = 14)
suffix_entry = Entry(newWindow, textvariable = suffix, width = 5)
addr1_entry = Entry(newWindow, textvariable = addr1, width = 51)
addr2_entry = Entry(newWindow, textvariable = addr2, width = 51)
city_entry = Entry(newWindow, textvariable = city, width = 32)
state_entry = Entry(newWindow, textvariable = state, width = 3)
zipcode_entry = Entry(newWindow, textvariable = zipcode, width = 13)
`enter code here`# Placing the Entry boxes:
fname_entry.place(x=15, y = 69)
mname_entry.place(x=155, y = 69)
lname_entry.place(x=295, y = 69)
suffix_entry.place(x=435, y = 69)
addr1_entry.place(x=15, y = 119)
addr2_entry.place(x=15, y = 169)
city_entry.place(x=15, y = 219)
state_entry.place(x=318, y = 219)
zipcode_entry.place(x=360, y = 219)
# Creates a Button and assigns it to the Variable: register. It is a gray, borderless button that when clicked, calls the saveInfo function.
register = Button(text = "REGISTER", bordercolor = 'gray', padx = 10, pady = 5, background='#BDBDBD', borderless = 'true', relief = 'groove', command = saveInfo)
# Places the Button
register.place (in_=newWindow, x = 200, y = 275)
newWindow.mainloop()
# End of createWindow function
style1 = ttk.Style()
style2 = ttk.Style()
style3 = ttk.Style()
style1.configure('topFrame.TFrame', background='green', borderwidth=4, relief='raised')
style2.configure('bottomFrame.TFrame', background = 'blue', borderwidth=6, relief = 'raised')
style3.configure('SrchLabel.TLabel')
eFrame = ttk.Frame(mainWindow, width=1060, height=200, style='topFrame.TFrame').grid()
rFrame = ttk.Frame(mainWindow, width=1060, height=600, style='bottomFrame.TFrame').grid()
# eFrame: Title text shown before the search terms entry box
srchFrame = ttk.Label(mainWindow, style = 'SrchLabel.TLabel', text = 'Patron Search')
srchFrame.place (x='30', y='40')
# eFrame: Search terms entry box
srchVar = StringVar()
srchEntry = tk.Entry(eFrame, bd = '1', width = '35')
srchEntry.place (x='130', y='37')
# eFrame: Button to execute Search
srchButton = Button(eFrame, text = 'Search', height = 30, width = 60, bd = '1')
srchButton.place(x = '470', y = '35')
# eFrame: Button to create New Record
newButton = Button(eFrame, text = 'New', height = 30, width = 60, bd = '1', command = createWindow)
newButton.place(x = '550', y = '35')
# rFrame: TAB Window Frame = from ttk Notebook
tabControl = ttk.Notebook(rFrame, width = 995, height = 528, style = 'rTabs.TNotebook')
# rFrame: TAB Elements
tab1 = ttk.Frame(tabControl)
tab2 = ttk.Frame(tabControl)
tab3 = ttk.Frame(tabControl)
tab1=Frame(tabControl, background="#ffffff")
tab1.pack()
tab2=Frame(tabControl, background="#ffffff")
tab2.pack()
tab3=Frame(tabControl, background="#ffffff")
tab3.pack()
# rFrame: TAB Titles and Window placement
tabControl.add(tab1, text ='Patron')
tabControl.add(tab2, text ='Orders')
tabControl.add(tab3, text = 'Donations')
tabControl.place(x='5', y='205')
# TAB 1 Content
ttk.Label(tab1, text ='Patron Data').grid(column = 0, row = 0, padx = 30, pady = 30)
# TAB 2 Content
ttk.Label(tab2, text ='Order History and Info').grid(column = 0, row = 0, padx = 30, pady = 30)
# TAB 3 Content
ttk.Label(tab3, text ='Donation Info').grid(column = 0, row = 0, padx = 30, pady = 30)
# mainWindow: MENUBAR
menubar = Menu(mainWindow)
# mainWindow: Filemenu
file = Menu(menubar, tearoff = 1)
menubar.add_cascade(label ='File', menu = file)
file.add_command(label ='New File', command = None)
file.add_command(label ='Open...', command = None)
file.add_command(label ='Save', command = None)
file.add_separator()
file.add_command(label ='Exit', command = mainWindow.destroy)
# mainWindow: Editmenu
edit = Menu(menubar, tearoff = 1)
menubar.add_cascade(label ='Edit', menu = edit)
edit.add_command(label ='Cut', command = None)
edit.add_command(label ='Copy', command = None)
edit.add_command(label ='Paste', command = None)
edit.add_command(label ='Select All', command = None)
edit.add_separator()
edit.add_command(label ='Find...', command = None)
edit.add_command(label ='Find again', command = None)
# mainWindow: Helpmenu
help_ = Menu(menubar, tearoff = 1)
menubar.add_cascade(label ='Help', menu = help_)
help_.add_command(label ='Tk Help', command = None)
help_.add_command(label ='Demo', command = None)
help_.add_separator()
help_.add_command(label ='About Tk', command = None)
mainWindow.config(menu = menubar)
mainWindow.mainloop()
Again, I am not looking for advice on how to write better code, as I am just learning (2 weeks in). However any help you can provide in letting me know what I am doing wrong and where I can find an answer would be greatly appreciated!
Thanks in advance!
I've created a temperature converter programme in which the calculated temperature from an entry widget gets displayed in a separate label, what I need to do is to grab that converted variable and put it into a list.
I think that making a connected entry widget to the label widget would work where they are connected so I could grab the variable using the .get method but that would look awfully messy. Is there any other way I could proceed with this?
This is my first post and I am a beginner in Python, very sorry if the code looks messy and if I included too much code.
data = []
tempVal = "Celcius"
def store_temp(sel_temp):
global tempVal
tempVal = sel_temp
class Calculator:
def __init__(self, num_a, num_b):
self.num_a= num_a
self.num_b = num_b
def convert(self):
if tempVal == 'Fahrenheit':
return float((float(self.num_a) - 32)* 5 / 9)
if tempVal == 'Celcius':
return float((float(self.num_a) * 9/ 5) + 32)
def display_add(entry_numa,entry_numb,label_answer):
#get the value from entry_numa
num_a = entry_numa.get()
num_b = entry_numb.get()
num_a = str(num_a)
num_b = str(num_b)
#create an object
global data
calc = Calculator(num_a,num_b)
label_answer['text'] = calc.convert()
data += [calc]
def calc_history():
global data
#creat e another window
window_calc_list = Tk()
window_calc_list.geometry("400x200")
#create a listbox
listbox_calc_list = Listbox(window_calc_list, width= 300)
listbox_calc_list.pack()
listbox_calc_list.insert(END, "list of data")
for info in data:
listbox_calc_list.insert(END, str(info.num_a) + " " + str(info.num_b) + " " )
window_calc_list.mainloop()
def main():
window = Tk()
window.geometry("500x150")
validate_letter = window.register(only_letters)
validate_nb = window.register(only_numbers_max_3)
label = Label(window, width = 30, background = 'lightblue', text='enter temperature, only numbers')
label.grid(row=0, column=0)
entry_numa = Entry(window, width = 30, validate="key", validatecommand=(validate_nb, '%d', '%P'))
entry_numa.grid(row = 0, column = 1)
#create another label and entry object for num_b
label_numb = Label(window, width = 30, background = 'lightblue', text='enter location, only letters')
label_numb.grid(row=1, column=0)
entry_numb = Entry(window, width = 30, validate="key", validatecommand=(validate_letter, '%d', '%S'))
entry_numb.grid(row = 1, column = 1)
#create another label to display answer
label_answer = Label(window, width = 30, background = 'lightyellow')
label_answer.grid(row = 2, column = 1)
entry_answer = Entry(window, width = 30)
entry_answer.grid(row = 2, column = 0)
button_add = Button(window, text = "ADD", command = lambda: display_add(entry_numa,entry_numb,label_answer))
button_add.grid(row=3, column = 0)
button_delete = Button(window, text = "DELETE", command = lambda: delete_data(data))
button_delete.grid(row=3, column = 2)
#create another button to display all previous calculations
button_display = Button(window,text = "calc_history", command = lambda: calc_history())
button_display.grid(row=3, column = 1)
var = StringVar()
dropDownList = ["Celcius", "Fahrenheit"]
dropdown = OptionMenu(window, var,dropDownList[0], *dropDownList, command=store_temp)
dropdown.grid(row=0, column=2)
window.mainloop()
A tk.Label displayed value can be accessed via the text property
, labelwidgetname['text'].
Depeneding on when and how you want the independent list of stored values
to be updated there are a variety of options. The example shows one if the
user is required to press a submission button. This could be adapted,
for example,when the tempreture calculation is performed.
Of course it would be simpler to update the list of stored values directly at the point in the script where the calculated tempreture for the label text has been derived.
import tkinter as tk
stored_values = []
def add_labelvalue_tolist(temp):
'''Store label value to list.'''
stored_values.append(temp)
print('contents of list', stored_values)
def add_entry_tolabel(event):
display_label['text'] = user_entry.get()
ROOT = tk.Tk()
user_entry = tk.Entry()
user_entry.grid(column=0, row=0)
user_entry.bind('<KeyRelease>', add_entry_tolabel)
display_label = tk.Label()
display_label.grid(column=1, row=0)
# update list via button command linked to label text value
add_button = \
tk.Button(text='add to list',
command=lambda:add_labelvalue_tolist(display_label['text']))
add_button.grid(column=0, row=1)
ROOT.mainloop()
try making a function that is like this
def letterused():
converter=(letter.get())# letter is a entry box at the bottom is the code
converted.set(converter)
for i in range(1):
used_letters1.append(converter) #list
letter = ttk.Entry(root, width = 20,textvariable = letter)
letter.pack()
The problem is that when some objects are being created in the double click subroutine the grid goes messed up. The tree view expands a bit to the right and labels and buttons which are suppose to go in column 1 look like they are in column 3(went off button above tree view which is in column 3). Also when I try making a button it puts it above the tree view no matter its row.
Code:
from tkinter import *
import os
import datetime
import sqlite3
from tkinter.ttk import Combobox,Treeview,Scrollbar
class Application(Frame):
""" Binary to Decimal """
def __init__(self, master):
""" Initialize the frame. """
super(Application, self).__init__(master)
self.grid()
self.create_GUI()
def Quit(self):
self.master.destroy()
def create_GUI(self):
self.title_lbl = Label(self, text = "Students")
self.title_lbl.grid(row = 0, column = 2)
self.fn_lbl = Label(self, text = "First Name:")
self.fn_lbl.grid(row = 1 , column = 1)
self.fn_txt = Entry(self)
self.fn_txt.grid(row = 1, column = 2)
self.ln_lbl =Label(self, text = "Last Name:")
self.ln_lbl.grid(row = 2, column = 1)
self.ln_txt = Entry(self)
self.ln_txt.grid(row = 2, column = 2)
self.q_btn = Button(self, text = "Back",padx=80,pady=10, command = lambda: self.Quit)
self.q_btn.grid(row = 3, column = 0)
self.s_btn = Button(self, text = "search",padx=80,pady=10, command = lambda: self.search())
self.s_btn.grid(row = 3,column = 3)
self.tree = Treeview(self.master,height = 6)
self.tree["columns"] = ("StudentID","First Name","Last Name")#,"House Number", "Street Name", "Town Or City Name","PostCode","MobilePhoneNumber")
self.tree.column("StudentID",width = 20)
self.tree.column("First Name",width = 40)
self.tree.column("Last Name", width = 40)
## self.tree.column("House Number", width = 60)
## self.tree.column("Street Name", width = 60)
## self.tree.column("Town Or City Name", width = 60)
## self.tree.column("PostCode", width = 60)
## self.tree.column("MobilePhoneNumber", width = 60)
self.tree.heading("StudentID",text="StudentID")
self.tree.heading("First Name",text="First Name")
self.tree.heading("Last Name",text="Last Name")
## self.tree.heading("House Number",text="House Number")
## self.tree.heading("Street Name",text="Street Name")
## self.tree.heading("Town Or City Name",text="Town Or City Name")
## self.tree.heading("PostCode",text="PostCode")
## self.tree.heading("MobilePhoneNumber",text="MobilePhoneNumber")
self.tree["show"] = "headings"
yscrollbar = Scrollbar(self.master, orient='vertical', command=self.tree.yview)
xscrollbar = Scrollbar(self.master, orient='horizontal', command=self.tree.xview)
self.tree.configure(yscroll=yscrollbar.set, xscroll=xscrollbar.set)
yscrollbar.grid(row=4, column=3, padx=2, pady=2, sticky=NS)
self.tree.grid(row=4,column=0,columnspan =5, padx=2,pady=2,sticky =NSEW)
self.tree.bind("<Double-1>",lambda event :self.OnDoubleClick(event))
def OnDoubleClick(self, event):
curItem = self.tree.focus()
contents =(self.tree.item(curItem))
StudentDetails = contents['values']
print(StudentDetails)
self.tStudentID=StringVar()
self.tFirstName = StringVar()
self.tLastName = StringVar()
self.tHouseNumber = StringVar()
self.tStreetName = StringVar()
self.tTownOrCityName = StringVar()
self.tPostCode = StringVar()
self.tEmail = StringVar()
self.tMobilePhoneNumber = StringVar()
self.tStudentID.set(StudentDetails[0])
self.tFirstName.set(StudentDetails[1])
self.tLastName.set(StudentDetails[2])
self.tHouseNumber.set(StudentDetails[3])
self.tStreetName.set(StudentDetails[4])
self.tTownOrCityName.set(StudentDetails[5])
self.tPostCode.set(StudentDetails[6])
self.tEmail.set(StudentDetails[7])
self.tMobilePhoneNumber.set(StudentDetails[8])
self.inst_lbl0 = Label(self.master, text = "Student ID").grid(row=5,column=0,sticky=W)
self.NStudentID = Label(self.master, textvariable=self.tStudentID).grid(row =5,column=1,stick=W)
self.inst_lbl1 = Label(self.master, text = "First Name").grid(row=6,column=0,sticky=W)
self.NFirstName = Entry(self.master, textvariable=self.tFirstName).grid(row =6,column=1,stick=W)
self.inst_lbl2 = Label(self.master, text = "Last Name").grid(row=7,column=0,sticky=W)
self.NLastName = Entry(self.master, textvariable=self.tLastName).grid(row =7,column=1,stick=W)
self.inst_lbl3 = Label(self.master, text = "House Number").grid(row=8,column=0,sticky=W)
self.HouseNumber = Entry(self.master,textvariable=self.tHouseNumber).grid(row=8,column=1,sticky=W)
self.inst_lbl4 = Label(self.master, text = "Street Name").grid(row=9,column=0,sticky=W)
self.StreetName =Entry(self.master,textvariable=self.tStreetName).grid(row=9,column=1,sticky=W)
self.inst_lbl5 = Label(self.master, text = "Town or City Name").grid(row=10,column=0,sticky=W)
self.TownOrCityName =Entry(self.master,textvariable=self.tTownOrCityName).grid(row=10,column=1,sticky=W)
self.inst_lbl6 = Label(self.master, text = "Postcode").grid(row=11,column=0,sticky=W)
self.PostCode = Entry(self.master,textvariable=self.tPostCode).grid(row=11,column=1,sticky=W)
self.inst_lbl7 = Label(self.master, text = "Email").grid(row=12,column=0,sticky=W)
self.Email =Entry(self.master,textvariable=self.tEmail).grid(row=12,column=1,sticky=W)
self.inst_lbl8 = Label(self.master, text = "Mobile phonenumber").grid(row=13,column=0,sticky=W)
self.MobilePhoneNumber =Entry(self.master,textvariable=self.tMobilePhoneNumber).grid(row=13,column=1,sticky=W)
self.btnSaveChanges = Button(self, text = "save changes",padx=80,pady=10,command = lambda:self.SaveChanges).grid(row=14,column=0,sticky=W)
#self.btnSaveChanges = Button(self, text = "delete record",padx=80,pady=10,command = lambda:self.DeleteRecord).grid(row=14,column=1,sticky=W)
def search(self):
FirstName = self.fn_txt.get()
LastName = self.ln_txt.get()
with sqlite3.connect("GuitarLessons.db") as db:
cursor = db.cursor()
cursor.row_factory = sqlite3.Row
sql = "select StudentID,FirstName,LastName,HouseNumber,StreetName,TownOrCityName,PostCode,Email,MobilePhoneNumber"\
" from tblStudents"\
" where FirstName like ?"\
" and LastName like ?"
cursor.execute(sql,("%"+FirstName+"%","%"+LastName+"%",))
StudentList = cursor.fetchall()
print(StudentList)
self.loadStudents(StudentList)
def loadStudents(self,StudentList):
for i in self.tree.get_children():
self.tree.delete(i)
for student in StudentList:
self.tree.insert("" , 0,values=(student[0],student[1],student[2],student[3],student[4],student[5],student[6],student[7],student[8]))
def SaveChanges(self):
with sqlite3.connect("GuitarLessons.db") as db:
cursor = db.cursor()
sql = "update tblStudents set FirstName =?,LastName=?,HouseNumber=?,StreetName=?,TownOrCityName=?,PostCode=?,Email=?,MobilePhoneNumber=? where StudentID=?"
cursor.execute(sql,("%"+NFirstName+"%","%"+NLastName+"%","%"+NHouseNumber+"%","%"+NStreetName+"%","%"+NTownOrCityName+"%","%"+NPostCode+"%","%"+NEmail+"%","%"+NMobilePhoneNumber+"%"))
db.commit()
def DeleteRecord(self):
print("")
root = Tk()
root.title("booking system")
root.geometry("800x800")
root.configure(bg="white")
app = Application(root)
root.mainloop()
The mistake you are making is that you're trying to put everything into one massive grid, but the code to populate that grid is scattered throughout your program. Your UI clearly has three distinct sections, you should organize your GUI that way.
Create a frame for the top, a frame for the treeview, and a frame for the bottom section. You can use pack to place these in the master window, one on top of the other. Then, place your other widgets in the appropriate frame. This way, changes you make in one section (adding or removing columns or rows, switching to pack, etc) won't affect the other areas.
I get the AttributeError: float object has no attribute set at Line 61, in calcmpg.self.mpg.set(self.mpg)
How do I correct this?
Here is the program I've written:
This program prompts the user to enter number of miles driven and gallons consumed to calculate MPG.
import tkinter
import tkinter.messagebox
class MilesPerGallonGUI:
def __init__(self):
#create main window
self.main_window = tkinter.Tk()
#create frames
self.frame1 = tkinter.Frame(self.main_window)
self.frame2 = tkinter.Frame(self.main_window)
self.frame3 = tkinter.Frame(self.main_window)
self.frame4 = tkinter.Frame(self.main_window)
#create label widgets
self.label1 = tkinter.Label(self.frame1, text = 'Enter miles: ')
self.label2 = tkinter.Label(self.frame2, text = 'Enter gallons: ')
#create entry widgets
self.entry1 = tkinter.Entry(self.frame1, width = 10)
self.entry2 = tkinter.Entry(self.frame2, width = 10)
#pack
self.label1.pack (side = 'left')
self.entry1.pack (side = 'left')
self.label2.pack (side = 'left')
self.entry2.pack (side = 'left')
#
self.mpg = tkinter.StringVar()
self.res = tkinter.Label(self.frame3, text = 'The MPG value is: ')
self.res_label = tkinter.Label(self.frame3, textvariable = self.mpg)
self.res.pack(side = 'left')
self.res_label.pack(side = 'left')
self.calc = tkinter.Button(self.frame4, text = 'Calculate MPG', command = self.calcmpg)
self.quit_button = tkinter.Button(self.frame4, text = 'Quit', command = self.main_window.destroy)
self.calc.pack(side = 'left')
self.quit_button.pack(side = 'left')
self.frame1.pack()
self.frame2.pack()
self.frame3.pack()
self.frame4.pack()
tkinter.mainloop()
#calcmpg for a callback function for the calculate button
def calcmpg(self):
self.test1 = float(self.entry1.get())
self.test2 = float(self.entry2.get())
self.mpg = float(self.test1/self.test2)
self.mpg.set(self.mpg)
gu = MilesPerGallonGUI()
You set the variable to a float first:
self.mpg = float(self.test1/self.test2)
self.mpg.set(self.mpg)
so on that second line you are trying to use the old StringVar object, but that's no longer there.
Make mpg a local variable instead:
new_mpg = float(self.test1/self.test2)
self.mpg.set(new_mpg)
By not replacing self.mpg with a float, but using a new, separate local instead, you can still use the StringVar object methods.
Replace the lines
self.mpg = float(self.test1/self.test2)
self.mpg.set(self.mpg)
by
self.mpg.set(float(self.test1/self.test2))
The problem is here:
self.mpg = float(self.test1/self.test2)
self.mpg.set(self.mpg)
Earlier, you have self.mpg = tkinter.StringVar(). In the calcmpg method, however, you assign self.mpg to a float. A float does not have a set method.