Python treeview and grid - python

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.

Related

How do I fix this error? self.category_id.set(row[1]), IndexError: string index out of range

I'm adding data into sqlite table and when I try to update the table, I'm getting this error 'string index not in range'.
Again when I execute the update command, all the columns gets updated except the identity column but my intention is only to update a selected row.
what I not doing right from the code below>
Your assistance will be highly appreciated.
The error is happening in the function update_record(self).
This is my code:
import tkinter
from tkinter import *
from tkinter import ttk
import tkinter.messagebox
import sqlite3
root =Tk()
root.title('Accounting App')
root.config(bg='#3d6466')
root.geometry("520x400")
root.resizable(False, False)
style = ttk.Style()
style.theme_use('alt')
style.configure("TCombobox", fieldbackground="Grey", background="Grey")
class Backend():
def __init__(self):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
#self.conn.execute("""DROP TABLE IF EXISTS account_type""")
self.conn.execute("""CREATE TABLE IF NOT EXISTS account_type(
id INTEGER PRIMARY KEY,
category_id INTEGER NOT NULL,
category_type TEXT NOT NULL
)"""),
self.conn.commit()
# elf.conn.close()
# =========Account Type======
class Account_type():
def insert_account_type(self, category_id, category_type):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
self.cur.execute("""INSERT INTO account_type(category_id,category_type) VALUES(?,?);""",
(category_id, category_type,))
self.conn.commit()
self.conn.close()
def view_account_type(self):
self.conn = sqlite3.connect('accounting.db')
self.cur = self.conn.cursor()
self.cur.execute("SELECT * FROM account_type")
rows = self.cur.fetchall()
self.conn.close()
return rows
acc_type = Backend.Account_type()
tb = Backend()
class Front_end():
def __init__(self, master):
# Frames
global cur
global conn
conn = sqlite3.connect('accounting.db')
cur = conn.cursor()
# Frames
self.left_frame = LabelFrame(master,bg='#3d6466', relief=SUNKEN,width=200)
self.left_frame.pack(fill = 'both',expand = YES , padx = 5,side=LEFT,anchor=NW)
self.right_frame = LabelFrame(master, bg='#3d6466', relief=SUNKEN)
self.right_frame.pack(fill = 'both',expand = YES ,side=LEFT,anchor=NW)
self.top_right_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN,text='Details',fg='maroon')
self.top_right_frame.pack(fill=BOTH,side=TOP, anchor=NW,expand=YES)
self.top_r_inner_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN, text='...', fg='maroon',height=10)
self.top_r_inner_frame.pack(fill=BOTH, side=TOP, anchor=SW, expand=YES)
self.bottom_right_frame = LabelFrame(self.right_frame, bg='#3d6466', relief=SUNKEN, text='Field View', fg='maroon')
self.bottom_right_frame.pack(fill=BOTH,side=TOP, anchor=SW, expand=YES)
self.my_canvas = Canvas(self.top_right_frame,bg='#3d6466')
self.my_canvas.pack(side=LEFT,fill='both', expand=YES)
# vertical configuration of scrollbar
self.yscrollbar = ttk.Scrollbar(self.top_right_frame, orient=VERTICAL, command = self.my_canvas.yview)
self.yscrollbar.pack(side=RIGHT,fill='both')
self.my_canvas.config(yscrollcommand = self.yscrollbar.set)
self.top_right_frame = Frame(self.my_canvas, bg='#3d6466', relief=SUNKEN)
self.my_canvas.create_window((0,0),window=self.top_right_frame, anchor=NW)
self.my_canvas.bind('<Configure>',lambda e:self.my_canvas.configure(scrollregion = self.my_canvas.bbox('all')))
self.side_frame = LabelFrame(self.left_frame,bg='#3d6466',relief=SUNKEN,text='Menu Buttons',fg='maroon',)
self.side_frame.pack(side=TOP,anchor=NW,expand=YES )
# Side Buttons
self.btn1 = Button(self.side_frame, text='Main Account Types', bg='#3d6466', font=('cambria', 12), anchor=W,
fg='white', width=18,height=2,command=self.main_account)
self.btn1.grid(row=0, column=0, sticky=W)
def main_account(self):
# variables
self.category_id = StringVar()
self.category_type = StringVar()
self.category_search =StringVar()
# functions
def add_main_accounts(self):
if self.category_id.get() == "":
tkinter.messagebox.showinfo('All fields are required')
else:
Backend.Account_type.insert_account_type(self,
self.category_id.get(),self.category_type.get())
tkinter.messagebox.showinfo('Entry successful')
def display_account_types(self):
self.trv.delete(*self.trv.get_children())
for rows in Backend.Account_type.view_account_type(self):
self.trv.insert("", END, values=rows)
def get_account_type(e):
selected_row = self.trv.focus()
data = self.trv.item(selected_row)
row = data["values"]
"""Grab items and send them to entry fields"""
self.category_id.set(row[1])
self.category_type.set(row[2])
def clear(self):
self.category_id.set("")
self.category_type.set("")
**def update_record(self):
selected = self.trv.focus()
self.trv.item(selected, values=(
self.category_id.get(), self.category_type.get()))
conn = sqlite3.connect("accounting.db")
cur = conn.cursor()
if self.category_id.get() == "" or self.category_type.get() == "" :
tkinter.messagebox.showinfo('All fields are required!')
return
update_record = tkinter.messagebox.askyesno('Confirm please',
'Do you want to update records?')
if update_record > 0:
cur.execute(
"UPDATE account_type SET category_id=:cat_id, category_type=:type",
{'cat_id': self.category_id.get(), 'type': self.category_type.get()})
tkinter.messagebox.showinfo('Record update successful!')
conn.commit()**
# call the function for Clearing the fields
clear(self)
conn.close()
"""=================TreeView==============="""
# Scrollbars
ttk.Style().configure("Treeview", background = "#3d6466", foreground = "white", fieldbackground = "grey")
scroll_x = Scrollbar(self.bottom_right_frame, orient = HORIZONTAL)
scroll_x.pack(side = BOTTOM, fill = X)
scroll_y = Scrollbar(self.bottom_right_frame, orient = VERTICAL)
scroll_y.pack(side = RIGHT, fill = Y)
# Treeview columns & setting scrollbars
self.trv = ttk.Treeview(self.bottom_right_frame, height=5, columns=
('id','category_id', 'category_type'), xscrollcommand = scroll_x.set, yscrollcommand = scroll_y.set)
# Treeview style configuration
ttk.Style().configure("Treeview", background = "#3d6466", foreground = "white", fieldbackground = "#3d6466")
# Configure vertical and Horizontal scroll
scroll_x.config(command = self.trv.xview)
scroll_y.config(command = self.trv.yview)
# Treeview Headings/columns
self.trv.heading('id', text = 'NO')
self.trv.heading('category_id', text = 'Category ID')
self.trv.heading('category_type', text = 'Category Type')
self.trv['show'] = 'headings'
# Treeview columns width
self.trv.column('id', width = 50)
self.trv.column('category_id', width = 70)
self.trv.column('category_type', width = 90)
self.trv.pack(fill = BOTH, expand = YES,anchor = NW)
# Binding Treeview with data
self.trv.bind('<<TreeviewSelect>>',get_account_type) # trv.bind('<Double-1>',"")
# Account Types Labels
self.lbl1 = Label(self.top_right_frame,text = 'Category ID',anchor = W,width=12,font = ('cambria',13,),bg = '#3d6466')
self.lbl1.grid(row = 0,column = 0,pady = 5)
self.lbl1 = Label(self.top_right_frame, text='Category Type', anchor=W, width=12, font=('cambria', 13,), bg='#3d6466')
self.lbl1.grid(row=1, column=0, pady=5)
self.lbl2 = Label(self.top_right_frame, text='Search Account', anchor=W, width=12, font=('cambria', 13,),
bg='#3d6466')
self.lbl2.grid(row=6, column=0, pady=5)
# Account Type Entries
self.entry1 = Entry(self.top_right_frame,textvariable = self.category_id,font = ('cambria',13,),bg = 'Grey',width=14)
self.entry1.grid(row = 0,column=1,sticky = W,padx = 4,columnspan=2)
self.entry1 = Entry(self.top_right_frame, textvariable=self.category_type, font=('cambria', 13,), bg='Grey', width=14)
self.entry1.grid(row=1, column=1, sticky=W, padx=4, columnspan=2)
self.entry2 = Entry(self.top_right_frame, textvariable=self.category_search, font=('cambria', 13,), bg='Grey', width=14)
self.entry2.grid(row=6, column=1, sticky=W, padx=4, columnspan=2)
# Buttons
self.btn_1 = Button(self.top_right_frame,text='Add',font=('cambria',12,'bold'),bg='#3d6466',
activebackground='green', fg = 'white',width=12,height = 1,relief=RAISED,
command = lambda :[add_main_accounts(self),display_account_types(self),clear(self)])
self.btn_1.grid(row = 3,column = 0,pady=6, padx=6)
self.btn_2 = Button(self.top_right_frame, text = 'View',command=lambda :[display_account_types(self),clear(self)],
font=('cambria', 12, 'bold'), bg = '#3d6466', activebackground='green',
fg ='white', width=12, height = 1, relief=RAISED)
self.btn_2.grid(row = 3, column=1,padx=0)
self.btn_3 = Button(self.top_right_frame, text = 'Update', command= lambda :[update_record(self),
display_account_types(self)],font=('cambria', 12, 'bold'), bg = '#3d6466',
activebackground = 'green', fg='white', width = 12, height = 1, relief=RAISED)
self.btn_3.grid(row = 4, column = 0,pady=6,padx=10)
# calling the class
app = Front_end(root)
root.mainloop()
Your update function updates all the records exist. To avoid this you should use WHERE. Here its fixed version
def update_record(self):
selected = self.trv.focus()
oldValues = self.trv.item(selected)["values"]
self.trv.item(selected, values=(oldValues[0],
self.category_id.get(), self.category_type.get()))
conn = sqlite3.connect("accounting.db")
cur = conn.cursor()
if self.category_id.get() == "" or self.category_type.get() == "" :
tkinter.messagebox.showinfo('All fields are required!')
return
update_record = tkinter.messagebox.askyesno('Confirm please',
'Do you want to update employee records?')
if update_record > 0:
cur.execute(
"UPDATE account_type SET category_id=:cat_id, category_type=:type WHERE id=:id_value",
{'cat_id': self.category_id.get(), 'type': self.category_type.get(), "id_value": oldValues[0]})
tkinter.messagebox.showinfo('Record update successful!')
conn.commit()
# call the function for Clearing the fields
clear(self)
conn.close()
We used selected rows idx etc.
However your error string index out of range is not about this. The function above going to fix your record update problem. Your error is because it tries to show a record value but after refreshed table, nothing is selected. So it returns empty.
def get_account_type(e):
selected_row = self.trv.focus()
data = self.trv.item(selected_row)
row = data["values"]
if(row == ""):
return
"""Grab items and send them to entry fields"""
self.category_id.set(row[1])
self.category_type.set(row[2])
Now if row is just an empty string, function stops executing and you get no errors.

Python Tkinter Spinboxes return value using for loops

I'm trying to use X many spin boxes as there are items in a list - so have put them on screen using a for loop.
However, I don't seem able to get them to return their value when I click a button.
aStarter = ["Starter 1", "Starter 2", "Starter 3"]
def getOrders():
aStarterOrder = []
aMainOrder = []
aDessertOrder = []
for i in aStarterQuantity:
aStarterOrder.append(StarterQuantity.get())
print(aStarterOrder)
aStarterQuantity = []
StarterQuantity = IntVar()
for i in range(len(aStarter)):
lbl = Label(self, text = aStarter[i]).grid(column = 0, row = 2 + i)
StarterQuantity = Spinbox(self, from_=0, to=20, width=5, command=callback, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 1, row = 2 + i)
print(StarterQuantity.get())
I have tried appending the StarterQuantity to an array inside of the for loop:
aStarterQuantity = []
StarterQuantity = IntVar()
for i in range(len(aStarter)):
lbl = Label(self, text = aStarter[i]).grid(column = 0, row = 2 + i)
StarterQuantity = Spinbox(self, from_=0, to=20, width=5, command=callback, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 1, row = 2 + i)
aStarterQuantity.append(StarterQuantity.get())
This returns a None Type error - I can't seem to get the value out of the spin box.
Any ideas?
Here is the full code (it's very much an early WIP!)
from tkinter import *
from tkinter.font import Font
import sqlite3
DatabaseFile = 'RMS.db'
connDatabase = sqlite3.connect(DatabaseFile)
#Creating a cursor to run SQL Commands
DatabaseSelect = connDatabase.cursor()
#Selecting all Menu Data
DatabaseSelect.execute("SELECT * FROM MENU")
MenuData = DatabaseSelect.fetchall()
class Main(Tk): #This sets up the initial Frame in a Window called Main
def __init__(self): #This creates a controller to use the Frames
Tk.__init__(self) #This creates a Window within the controller
self._frame = None #This sets the frame to have a value of None - this makes sure the main Window doesn't get destroyed by the switch frame function
self.switch_frame(Home)
def switch_frame(self, frame_class): #This function is used to switch frames. Self is the master frame, frame_class is the name of the Class (page) being passed int
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy() #Destroy any frames except the master
self._frame = new_frame #Make a new frame
self._frame.grid(column=0, row=0) #Put the frame in the top left
class Home(Frame):
def __init__(self, master):
Frame.__init__(self, master)
Label(self, text="The White Horse").grid(column = 0, row = 0)
btnPage1 = Button(self, text="Orders", command=lambda: master.switch_frame(Orders)).grid(column = 1, row = 0)
#Making a blank page with a return home button
class Orders(Frame): #This sets up a class called Page1 - Each new page will need a new class.
def __init__(self, master): #This sets up a controller to put things into the Frame
Frame.__init__(self, master) #Make the frame using the controller
#Get list of Starters from Menu Data
aStarter = ["Starter 1", "Starter 2", "Starter 3"]
aMain = []
aDessert = []
for i in MenuData:
if i[3] == "Starters":
aStarter.append(i[1])
if i[3] == "Main":
aMain.append(i[1])
if i[3] == "Dessert":
aDessert.append(i[1])
def getOrders():
aStarterOrder = []
aMainOrder = []
aDessertOrder = []
for i in aStarterQuantity:
aStarterOrder.append(StarterQuantity.get())
print(aStarterOrder)
def callback():
print(StarterQuantity.get())
#Starter Section
boxes = []
aStarterQuantity = []
StarterQuantity = IntVar()
for i in range(len(aStarter)):
lbl = Label(self, text = aStarter[i]).grid(column = 0, row = 2 + i)
StarterQuantity = Spinbox(self, from_=0, to=20, width=5, command=callback, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 1, row = 2 + i)
aStarterQuantity.append(StarterQuantity.get())
#Mains Sections
for i in range(len(aMain)):
lbl = Label(self, text = aMain[i]).grid(column = 6, row = 2 + i)
MainQuantity = Spinbox(self, from_=0, to=20, width=5, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 7, row = 2 + i)
#Dessert Section
for i in range(len(aDessert)):
lbl = Label(self, text = aDessert[i]).grid(column = 12, row = 2 + i)
DessertQuantity = Spinbox(self, from_=0, to=20, width=5, font=Font(family='Helvetica', size=20, weight='bold')).grid(column = 13, row = 2 + i)
btnHome = Button(self, text="Home", command=lambda: master.switch_frame(Home)).grid(column = 0, row = 1) #Add a Button
btnSubmitEntries = Button(self, text = "Submit", command = getOrders).grid(column = 0, row= 20)
Main = Main()
Main.geometry("1200x800")
Main.mainloop()
The problem seems to be that the grid method doesn't return anything, so StarterQuantity gets assigned None i.e. the default return value for a function.
for i in range(len(aStarter)):
lbl = Label(self, text=aStarter[i])
lbl.grid(column=0, row=2 + i)
sq_font = Font(family='Helvetica',
size=20,
weight='bold')
StarterQuantity = Spinbox(self,
from_=0,
to=20,
width=5, command=callback,
font=sq_font)
StarterQuantity.grid(column=1, row=2 + i)
aStarterQuantity.append(StarterQuantity.get())
This works in my case. (Pulled out the Font argument for Spinbox to increase readability on mobile).
Unrelated note; I don't know what code style you prefer/have to maintain and it is up to you of course, but I thought it might be helpful to mention that the naming style convention in Python (PEP8) is to use CamelCase for class names, lower_case_w_underscores for variable names and functions/methods, and SCREAMING_SNAKE for constants.

Is it possible to grab a label variable and put into list with tkinter

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()

how can I get the value of Entry Widget when the related class is called after login class

I'm trying to make a login window. I found a good example code here in Stackoverflow and added it with a simple code using Entry widget. After log in successfully, however, I can't get correct values of textvariable of Entry Widget even though I try to get them with Entry's instance.get().
I've tried many ways I could do. But, I can't find what's wrong.
I'm working with python 2.7. please help.
from Tkinter import *
import tkMessageBox as tm
class LoginFrame:
def __init__(self):
root = Tk()
self.label_1 = Label(root, text="Username")
self.label_2 = Label(root, text="Password")
self.entry_1 = Entry(root)
self.entry_2 = Entry(root, show="*")
self.label_1.grid(row=0, sticky=E)
self.label_2.grid(row=1, sticky=E)
self.entry_1.grid(row=0, column=1)
self.entry_2.grid(row=1, column=1)
self.checkbox = Checkbutton(root, text="Keep me logged in")
self.checkbox.grid(columnspan=2)
self.logbtn = Button(root, text="Login", command =
self._login_btn_clickked)
self.logbtn.grid(columnspan=2)
root.mainloop()
def _login_btn_clickked(self):
username = self.entry_1.get()
password = self.entry_2.get()
#print(username, password)
if username == "1" and password == "1":
#tm.showinfo("Login info", "Welcome John")
app = EntrySample()
app.window.mainloop()
else:
tm.showerror("Login error", "Incorrect username")
class EntrySample:
def __init__(self):
self.window = Tk()
self.window.title("Test Entry")
Label(self.window, text = "Kor").grid(row = 1,
column = 1, sticky = W)
self.kor = IntVar()
self.enKor = Entry(self.window, textvariable = self.kor,
justify = RIGHT).grid(row = 1, column = 2)
Label(self.window, text = "Eng").grid(row = 2,
column = 1, sticky = W)
self.eng = IntVar()
self.enEng = Entry(self.window, textvariable = self.eng,
justify = RIGHT).grid(row = 2, column = 2)
Label(self.window, text = "Math").grid(row = 3,
column = 1, sticky = W)
self.math = IntVar()
self.enMath = Entry(self.window, textvariable = self.math,
justify = RIGHT).grid(row = 3, column = 2)
btComputePayment = Button(self.window, text = "Calculate",
command = self.compute).grid(
row = 4, column = 2, sticky = E)
def compute(self):
total = self.kor.get()+self.eng.get()+self.math.get()
avg = total/3.0
print total
print '%3.2f' %avg
LoginFrame()

changing a buttons colour when that button clicked

I am making a maze where the user enters the dimensions and can then click on a button to change the colour of that button to black. What i eventually want is to be making an ai which will try to navigate the maze the user created with the black rectangle the ai not being allowed to go on.
The problem is i dont know how to change the properties of the button clicked as due to a nested loop being used for creation they all have the same name.
from tkinter import *
import tkinter as tk
from tkinter.ttk import Combobox,Treeview,Scrollbar
class MainMenu(Frame):
def __init__(self, master):
""" Initialize the frame. """
super(MainMenu, self).__init__(master)
self.grid()
self.frame1 = tk.LabelFrame(self, text="entering diemsions", width=300, height=130, bd=5)
self.frame1.grid(row=0, column=0, columnspan=3, padx=8)
self.frame2 = tk.LabelFrame(self, text="creating maze", width=300, height=130, bd=5)
self.frame2.grid(row=1, column=0, columnspan=3, padx=8)
self.create_GUI()
def create_GUI(self):
self.width_lbl = Label(self.frame1, text = "width:")
self.width_lbl.grid(row = 1 , column = 1)
self.width_txt = Entry(self.frame1)
self.width_txt.grid(row = 1, column = 2)
self.getdimensions_btn = Button(self.frame1, text = "enter dimensions",command = lambda:self.createmaze())
self.getdimensions_btn.grid(row = 1 , column = 3)
self.height_lbl = Label(self.frame1, text = "height:")
self.height_lbl.grid(row = 1 , column = 4)
self.height_txt = Entry(self.frame1)
self.height_txt.grid(row = 1, column = 5)
def createmaze(self):
width = int(self.width_txt.get())
height = int(self.height_txt.get())
for widthcount in range (width):
for heightcount in range(height):
self.maze_btn = Button(self.frame2, text = "",width = 4, height = 2)
self.maze_btn.grid(row = heightcount , column = widthcount)
self.maze_btn.bind("<Button-1>", self.disablebtn)
def disablebtn(self,event):
grid_info = event.widget.grid_info()
col = grid_info["column"]
col = int(col)
row = grid_info["row"]
row = int(row)
root = Tk()
root.title("hi")
root.geometry("500x500")
root.configure(bg="white")
app = MainMenu(root)
root.mainloop()

Categories

Resources