Python Gui not responding to database - python

The purpose of this post is to determine the error within the code, I have spent countless hours trying to alter the code to see what the error is. I am trying to add a employee to a database through a python GUI (tkinter). Currently it is only inserting " " information, this is checked within our the def delete with a print statement. A similar problem I am having with def delete however the information in the tuple is not displaying in a listBox. Does anyone have a solution to why these faults are occurring?
def addEmp():
top = Toplevel()
top.title("Add Employee")
top.geometry("470x385")
app = Frame(top)
app.grid()
firstName = StringVar()
lastName = StringVar()
address = StringVar()
payRate = StringVar()
inUnion = StringVar()
paymentMethod = StringVar()
grp1 = StringVar()
firstNameLabel = Label (app, text = "First Name:", font = 15)
firstNameLabel.grid(row = 0, column = 0)
firstNameEntry = Entry (app, text = "", textvariable = firstName)
firstNameEntry.grid(row = 0, column = 1)
surNameLabel = Label (app, text = "Surname:", font = 15)
surNameLabel.grid(row = 1, column = 0)
lastNameEntry= Entry (app, text = "", textvariable = lastName)
lastNameEntry.grid(row = 1, column = 1)
addressLabel = Label (app, text = "Address:", font = 15)
addressLabel.grid(row = 2, column = 0)
addressEntry = Entry (app, text = "", textvariable = address)
addressEntry.grid(row = 2, column = 1)
payRateLabel = Label (app, text = "Pay Rate Hourly:", font = 15)
payRateLabel.grid(row = 3, column = 0)
payRateEntry = Entry (app, text = "", textvariable = payRate)
payRateEntry.grid(row = 3, column = 1)
salaryLabel = Label (app, text = "Pay Rate Monthly:", font = 15)
salaryLabel.grid(row = 4, column = 0)
salaryEntry = Entry (app, text = "")
salaryEntry.grid(row = 4, column = 1)
payTypeLabel = Label (app, text = "Work Type:", font = 15)
payTypeLabel.grid(row = 5, column = 0)
radio1 = Radiobutton(app, text = "Full Time (Monthly Salary)", value = 'Monthly', variable = grp1)
radio1.grid(row = 6, column = 1)
radio2 = Radiobutton(app, text = "Part Time (Hourly Pay per Week)", value = 'Weekly', variable = grp1)
radio2.grid(row = 7, column = 1)
radio3 = Radiobutton(app, text = "Commission", value = 'Commission', variable = grp1)
radio3.grid(row = 8, column = 1)
paymentOptionsLabel = Label (app, text = "Payment Option:", font = 15)
paymentOptionsLabel.grid(row = 9, column = 0)
radio4 = Radiobutton(app, text = "Mail to current address", value = "Mail", variable = paymentMethod)
radio4.grid(row = 10, column = 1)
radio5 = Radiobutton(app, text = "Held by Paymaster", value = "Hold", variable = paymentMethod)
radio5.grid(row = 11, column = 1)
radio6 = Radiobutton(app, text = "Directly Deposit into bank account", value = "Bank", variable = paymentMethod)
radio6.grid(row = 12, column = 1)
unionLabel = Label (app, text = "Union:", font = 15)
unionLabel.grid(row = 13, column = 0)
radio1union = Radiobutton(app, text = "Yes", value = '1', variable = inUnion)
radio1union.grid(row = 14, column = 1)
radio2union = Radiobutton(app, text = "No", value = '0', variable = inUnion)
radio2union.grid(row = 15, column = 1)
submitButton = Button (app, command = addEmpSubmit, text = "Submit", font = 15)
submitButton.grid(row = 20, column = 3)
def addEmpSubmit():
c.execute("INSERT INTO employees (first_name, last_name, address, in_union, pay_type, payment_method) VALUES (?, ?, ?, ?, ?, ?)",
(str(firstName), str(lastName), str(address), str(inUnion), str(payType), str(paymentMethod)))
connection.commit()
if payType == "Weekly":
c.execute("UPDATE employees SET pay_rate=? WHERE employee_id=?", (payRate, c.lastrowid))
connection.commit()
elif payType == "Monthly":
c.execute("UPDATE employees SET monthly_salary=? WHERE employee_id=?", (monthlySalary, c.lastrowid))
connection.commit()
elif payType == "Commission":
c.execute("UPDATE employees SET monthly_salary=?, commission_rate=? WHERE employee_id=?",
(monthlySalary, commissionRate, c.lastrowid))
connection.commit()
def deleteEmp():
top = Toplevel()
top.title("Delete Employee")
top.geometry("470x385")
deleteList = Listbox(app)
deleteList.grid(row = 0, column = 0)
listItem = ""
c.execute("SELECT * FROM employees")
allEmp = c.fetchall()
for line in allEmp:
for item in line:
print(str(item))
listItem += str(item)
deleteList.insert(END, listItem)
connection.commit()
empIDLabel = Label (app, text = "Please select an Emp ID:", font = 15)
empIDLabel.grid(row = 1, column = 0)
empIDEntry = Entry (app, text = "")
empIDEntry.grid(row = 2, column = 0)
deleteButton = Button (app, text = "Delete", font = 15)
deleteButton.grid(row = 2, column = 1)

Read properly the documentation on ControlVariables / StringVar.
The values you provide for INSERT INTO - queries are not the values of the entry widgets.
>>> name=tk.StringVar()
>>> name.set("First Name")
>>> name
<Tkinter.StringVar instance at 0x01EB4CB0>
>>> str(name)
'PY_VAR0'
>>> name
<Tkinter.StringVar instance at 0x01EB4CB0>
>>> name.get()
'First Name'
Please make sure you post only code samples that can reproduce your error on (at least) your system. As for this reason it is very hard to reproduce the issues you have got.
Split your code up and debug it in smaller slices. Check the different components on their own (e.g. first the sql part with some dummy data but using variables, StringVars, etc.).
Do you receive any error messages? If so, please add them to your post so that we can see if you are struggling at a certain point. Something like - "my code is not working - why?" is hard to analyze if even possible with correct information.

Related

Tkinter - "Label" object is not callable ; NOT a case of naming an object after LABEL class [duplicate]

This question already has answers here:
I'm getting a TypeError. How do I fix it?
(2 answers)
TypeError: 'function' object is not subscriptable - Python
(4 answers)
Closed 6 months ago.
I'm working on a tkinter GUI API-based application.
I'm attempting to modularize my code in which each function has a specific task to do and some functions just call other functions.
In my case, I bind the search button to the function, search, whose job is to call other API-based functions, such as full_name.
When I did this, an error is thrown, saying that in search full_name() TypeError: 'Label' object is not callable
what's interesting is that
I see no mention of creating instances of Label classes in full_name()
when I bind the search button to function, full_name(), it works just fine. However, I want to bind it to a function that will call all API-based functions, and so far, it's not working
Here's the code below:
#MER for frames placement through .Grid()
#import necessary modules
from tkinter import *
from tkinter import ttk
from PIL import ImageTk, Image
from tkinter import messagebox
import requests
import json
root = Tk()
root.title("F1 Desktop Application")
root.geometry("500x600")
root.configure(bg="white")
#generate 2022 drivers-list [can scale to drivers-list by changing the]
drivers_list_request = requests.get("http://ergast.com/api/f1/2022/drivers.json")
#initialize empty-list
drivers_list = []
drivers_list_object = json.loads(drivers_list_request.content)
for elements in drivers_list_object["MRData"]["DriverTable"]["Drivers"]:
drivers_list.append(elements["givenName"] + " " + elements["familyName"])
#NEED TO UNDERSTAND PRECEDENCE BETWEEN WIDTH, HEIGHT SETTING, VS SPANS. STICKY MAKES PERFECT SENSE
top_frame = LabelFrame(root, width = 300, height = 125)
top_frame.grid(row = 0, column = 0, columnspan = 2)
top_frame.rowconfigure(0, minsize = 75)
top_frame.columnconfigure(0, minsize = 300)
# Update the Entry widget with the selected item in list
def check(e):
v= entry_box.get()
if v=='':
hide_button(menu)
else:
data=[]
for item in drivers_list:
if v.lower() in item.lower():
data.append(item)
update(data)
show_button(menu)
def update(data):
# Clear the Combobox
menu.delete(0, END)
# Add values to the combobox
for value in data:
menu.insert(END,value)
def fillout(event):
try:
entry_box.delete(0,END)
entry_box.insert(0,menu.get(menu.curselection()))
hide_button(menu)
#handle a complete deletion of entry-box via cursor double tap
except:
pass
def hide_button(widget):
widget.grid_remove()
def show_button(widget):
widget.grid()
def full_name():
user_input = entry_box.get()
lower_user_input = user_input.lower().split(" ")[1]
response = requests.get("http://ergast.com/api/f1/drivers/{}.json".format(lower_user_input))
print(response.status_code)
response_object = json.loads(response.content)
name = response_object["MRData"]["DriverTable"]["Drivers"][0]["givenName"] + " " + response_object["MRData"]["DriverTable"]["Drivers"][0]["familyName"]
print(name)
def search():
full_name()
#once works, then make API request
header_label = Label(top_frame, text = "F1 2022 Drivers App", font = ("Arial bold",14), bg = "white")
header_label.grid(row = 0, column = 0, padx = 30)
search_button = Button(top_frame, text = "search" , command = search)
search_button.grid(row = 1, column = 1)
entry_box= Entry(top_frame)
entry_box.grid(row = 1, column = 0)
entry_box.bind('<KeyRelease>',check)
menu= Listbox(top_frame, height = 4)
menu.grid(row = 2, column = 0)
menu.bind("<<ListboxSelect>>",fillout)
left_frame = LabelFrame(root, width = 250, height = 225, borderwidth = 0, highlightthickness = 2)
left_frame.grid(row = 1, column = 0, sticky = NW, padx = 10, pady = 15)
#left_frame.grid_propagate(False)
left_frame.rowconfigure(0, minsize = 100)
left_frame.columnconfigure(0, minsize = 200)
#left_frame_content = LabelFrame(, width = 125, height = 70)
#left_frame_content.grid(row = 1, column = 1, sticky = W)
basic_info = Label(left_frame, text = "Basic Info ", font = ("Arial bold",14))
basic_info.grid(row = 0, column = 0)
full_name = Label(left_frame, text = "Full Name :")
full_name.grid(row = 1, column = 0, sticky = W)
driver_code = Label(left_frame, text = "Driver Code : ")
driver_code.grid(row = 2, column = 0, sticky = W)
nationality = Label(left_frame, text = "Nationality : ")
nationality.grid(row = 3, column = 0, sticky = W)
bottom_left_frame = LabelFrame(root, width = 250, height = 225)
bottom_left_frame.grid(row = 2, column = 0, sticky = N, padx = 10)
bottom_left_frame.rowconfigure(0, minsize = 50)
bottom_left_frame.columnconfigure(0, minsize = 200)
F1_career = Label(bottom_left_frame, text = "F1 Career ", font = ("Arial bold",14))
F1_career.grid(row = 0, column = 0)
wins = Label(bottom_left_frame, text = "Wins :")
wins.grid(row = 1, column = 0, sticky = W)
wins.configure(text = "Wins :" + " 7")
poles = Label(bottom_left_frame, text = "Poles :")
poles.grid(row = 2, column = 0, sticky = W)
test = Label(bottom_left_frame, text = "test")
test.grid(row = 2, column = 1)
podiums = Label(bottom_left_frame, text = "Podiums :")
podiums.grid(row = 3, column = 0, sticky = W)
podiums.configure(text = "Podiums :" + "Lewis Hamilton")
drivers_championships = Label(bottom_left_frame, text = "Championships :")
drivers_championships.grid(row = 4, column = 0, sticky = W)
bottom_right_frame = LabelFrame(root, width = 250, height = 225)
bottom_right_frame.grid(row = 2, column = 1, sticky = W)
bottom_right_frame.rowconfigure(0, minsize = 50)
bottom_right_frame.columnconfigure(0, minsize = 150)
hide_button(menu)
root.mainloop()
Feel free to ask for more clarity. I would be grateful if anyone has a reason/solution
You have used the same name for a label:
full_name = Label(left_frame, text = "Full Name :")
So it will override the full_name().
Use another name for the label, for example full_name_label:
full_name_label = Label(left_frame, text = "Full Name :")
full_name_label.grid(row = 1, column = 0, sticky = W)

Python - tkinter - tree - database questions

I have a database with a customers table with the fields(id, name,surname, DOB).
I have created a treeview which displays name and surname but soon as i try to insert the DOB in to the treeview i get an error Column index 3 out of bounds.
Also please can you explain how treeview actually works as i have copied the code from a tutorial and adapted it but still dont fully understand it.
from tkinter import *
from tkinter import ttk
import sqlite3
import os.path
class Product:
db_name = 'database.db'
def __init__(self, wind):
self.wind = wind
self.wind.title('IT Products')
frame = LabelFrame (self.wind, text = 'Add new record')
frame.grid (row = 0, column = 1)
Label (frame, text = 'Name: ').grid (row = 1, column = 1)
self.name = Entry (frame)
self.name.grid(row = 1, column = 2)
Label (frame, text = 'Surname: ').grid (row = 2, column = 1)
self.price = Entry (frame)
self.price.grid(row = 2, column = 2)
ttk.Button (frame, text= 'Add record', command = self.adding).grid (row = 3, column =2 )
self.message = Label (text = '',fg = 'red')
self.message.grid (row = 3, column = 0)
self.tree = ttk.Treeview (height = 10, colum = 2)
self.tree.grid(row = 100, column = 0, columnspan = 100)
self.tree.heading('#0', text = 'Name', anchor = W)
self.tree.heading(2, text = 'Surname', anchor = W)
self.tree.heading(3, text = 'DOB', anchor = W)
self.tree.heading(3, text = "column B")
ttk.Button (text = 'Delete record', command = self.deleting).grid (row = 10, column = 5)
ttk.Button (text = 'Edit record').grid (row = 10, column = 1)
self.viewing_records()
def run_query (self, query, parameters = ()):
with sqlite3.connect(self.db_name) as conn:
cursor = conn.cursor()
query_result = cursor.execute (query, parameters)
conn.commit()
return query_result
def viewing_records(self):
records = self.tree.get_children()
for element in records:
self.tree.delete (element)
query = 'SELECT * FROM customers '
db_rows = self.run_query (query)
for row in db_rows:
## self.tree.insert('', 2, text=str(), values=(row[1], row[2],
row[3]))
self.tree.insert ('', 2, text = row[1], values=(row[1], row[2], row[3]))
def validation(self):
return len (self.name.get()) != 0 and len (self.price.get()) != 0
def adding (self):
if self.validation ():
query = 'INSERT INTO customersVALUES (NULL, ?, ?)'
parameters = (self.name.get(), self.price.get())
self.run_query (query, parameters)
self.message['text'] = 'Record {} added'.format (self.name.get())
self.name.delete (0, END)
self.price.delete (0,END)
else:
self.message['text'] = 'Name field or price is empty'
self.viewing_records()
def deleting (self):
self.message ['text'] = ''
try:
self.tree.item(self.tree.selection()) [ 'values'] [0]
except IndexError as e:
self.message[text] = 'Please select record'
return
self. message['text'] = ''
name = self.tree.item(self.tree.selection())['text']
query = 'DELETE FROM customers WHERE name = ?'
self.run_query(query, (name,))
self.message['text'] = 'Record {} deleted'.format(name)
self.viewing_records()
if __name__ == '__main__':
wind = Tk()
application = Product (wind)
wind.mainloop()
To avoid column index error, provide a list of column identifiers as show below:
self.tree = ttk.Treeview(height=10, columns=("lname", "sex", "sdate", "dob"))
self.tree.grid(row=100, column=0, columnspan=100)
self.tree.heading('#0', text='First Name', anchor=W)
self.tree.heading("lname", text='Last Name', anchor=W)
self.tree.heading("sex", text='Gender', anchor=W)
self.tree.heading("sdate", text='Start Date', anchor=W)
self.tree.heading("dob", text='Birth Date', anchor=W)

Python Status Bar

I am having a problem with adding status bar at the bottom of my program. When I do status.pack() it gives me this error : _tkinter.TclError: cannot use geometry manager grid inside . which already has slaves managed by pack. In My (
def init(self): ) If I delete (self.grid(sticky = W+E+N+S) then the window pops up an then the status bar is on the window, but then the rest of the program isn't there. I was wondering if someone give some insight on how to fix this
from tkinter.constants import END
from tkinter import ttk
from tkinter import *
from tkinter import font
from tkinter import messagebox
import tkinter as tk
import turtle
import random
from tkinter import filedialog
from PIL import Image
class App(Frame):
**********************************************************************************************************************************************************************************************************************8888
'''The code below Creates a Menu Bar across the top of the window '''
App = Tk()
menu = Menu (App)
App.config(menu = menu)
'''Lines 20 - 22 are basic setup for drop down meun box at the top of the page.'''
fileMenu = Menu(menu, tearoff = 0)
fileMenu.add_command(label = "New Project", command = turtle)
fileMenu.add_command(label = "Open", command = turtle)
fileMenu.add_command(label = "Save", command = turtle)
fileMenu.add_command(label = "Save as", command = turtle)
fileMenu.add_command(label = "Close", command = turtle)
menu.add_cascade(label = "File", menu = fileMenu)
fileMenu.add_separator()
'''This bit of code adds a separator between the buttons on the drop down menu.'''
fileMenu.add_command(label = "Exit", command = App.quit)
editMenu = Menu(menu, tearoff = 0)
editMenu.add_command(label = "Cut", command = turtle)
editMenu.add_command(label = "Copy", command = turtle)
editMenu.add_command(label = "Paste", command = turtle)
editMenu.add_command(label = "Delete", command = turtle)
editMenu.add_command(label = "Select All", command = turtle)
menu.add_cascade(label = "Edit", menu = editMenu)
helpMenu = Menu(menu, tearoff = 0)
helpMenu.add_command(label = "Help Index", command = turtle)
helpMenu.add_command(label = "About", command = turtle)
menu.add_cascade(label = "Help", menu = helpMenu)
************************************************************************************************************************************************************************************************************************************
''' The code below creates a Status Bar Across the bottom of the page. '''
status = Label(App, text = "This is a status bar...", bd = 1, relief = SUNKEN, anchor = W)
status.pack()
******************************************************************************************************************************************************************************************************************************
def __init__(self):
'''Sets up the window and widgets.'''
Frame.__init__(self, bg = "white" ) #this sets the background color of the window.
self.master.title("Auto Body Buddy Estimator") #this is the title of the screen
self.master.geometry("600x600") #this is the specs for the window size
self.master.resizable(0, 0) #this makes the window none resizable
self.master.columnconfigure(0, weight = 1)
self.master.rowconfigure(0, weight = 1)
self.grid(sticky = W+E+N+S)
#!/usr/bin/python
'''import cgi, os
import cgitb; cgitb.enable()
form = cgi.FieldStorage()
# Get filename here.
fileitem = form['filename']
# Test if the file was uploaded
if fileitem.filename:
# strip leading path from file name to avoid
# directory traversal attacks
fn = os.path.basename(fileitem.filename)
open('/tmp/' + fn, 'wb').write(fileitem.file.read())
message = ('The file "' + fn + '" was uploaded successfully')
else:
message = 'No file was uploaded'
print """\
Content-Type: text/html\n
<html>
<body>
<p>%s</p>
</body>
</html>
""" % (message,) '''
***********************************************************************************************************************************************************************
''' Creates the nested frame for the Data pane for the image '''
self._dataPane1 = Frame(self)#, bg = "orange")
self._dataPane1.grid(row = 0, column = 0)
self._pictureImage = PhotoImage(file = "../logo.gif")
self._imageLabel = Label(self._dataPane1, image = self._pictureImage)
self._imageLabel.grid(row = 0, column= 0)
*********************************************************************************************************************************************************************
''' Creates the nested frame for the Data pane'''
self._dataPaneEntryInfo = Frame(self, bg = "white")
self._dataPaneEntryInfo.grid(row = 1, column = 0)
''' Label and field for First Name '''
self._firstNameLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "First Name ")
self._firstNameLabel.grid(row = 0, column = 0)
self._firstNameVar = DoubleVar()
self._firstNameEntry = Entry(self._dataPaneEntryInfo, textvariable = self._firstNameVar)
self._firstNameEntry.grid(row = 0, column = 1)
''' Label and field for Last Name '''
self._LastNameLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Last Name ")
self._LastNameLabel.grid(row = 1, column = 0)
self._LastNameVar = DoubleVar()
self._LastNameEntry = Entry(self._dataPaneEntryInfo, textvariable = self._LastNameVar)
self._LastNameEntry.grid(row = 1, column = 1)
''' Label and field for Phone Number '''
self._phoneNumberLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Phone Number ")
self._phoneNumberLabel.grid(row = 2, column = 0)
self._phoneNumberVar = DoubleVar()
self._phoneNumberEntry = Entry(self._dataPaneEntryInfo, textvariable = self._phoneNumberVar)
self._phoneNumberEntry.grid(row = 2, column = 1)
''' Label and field for Email '''
self._EmailLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Email Address ")
self._EmailLabel.grid(row = 3, column = 0)
self._EmailVar = DoubleVar()
self._EmailEntry = Entry(self._dataPaneEntryInfo, textvariable = self._EmailVar)
self._EmailEntry.grid(row = 3, column = 1)
''' Label and field for Address '''
self._addressLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Address \n (OPITIONAL) ")
self._addressLabel.grid(row = 4, column = 0)
self._addressVar = DoubleVar()
self._addressEntry = Entry(self._dataPaneEntryInfo, textvariable = self._addressVar)
self._addressEntry.grid(row = 4, column = 1)
*********************************************************************************************************************************************************************
''' Label and field for Year of the Car '''
self._yearLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Year ")
self._yearLabel.grid(row = 0, column = 2)
self._yearVar = DoubleVar()
self._yearEntry = Entry(self._dataPaneEntryInfo, textvariable = self._yearVar)
self._yearEntry.grid(row = 0, column = 3)
''' Label and field for Make of the Car '''
self._makeLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Make ")
self._makeLabel.grid(row = 1, column = 2)
self._makeVar = DoubleVar()
self._makeEntry = Entry(self._dataPaneEntryInfo, textvariable = self._makeVar)
self._makeEntry.grid(row = 1, column = 3)
''' Label and field for Model of the Car '''
self._modelLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Model ")
self._modelLabel.grid(row = 2, column = 2)
self._modelVar = DoubleVar()
self._modelEntry = Entry(self._dataPaneEntryInfo, textvariable = self._modelVar)
self._modelEntry.grid(row = 2, column = 3)
''' Label and field for Package of the Car '''
self._packageLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "Package ")
self._packageLabel.grid(row = 3, column = 2)
self._packageVar = DoubleVar()
self._packageEntry = Entry(self._dataPaneEntryInfo, textvariable = self._packageVar)
self._packageEntry.grid(row = 3, column = 3)
''' Label and field for VIN # of the Car '''
self._vinLabel = Label(self._dataPaneEntryInfo, bg = "white", text = "VIN # ")
self._vinLabel.grid(row = 4, column = 2)
self._vinVar = DoubleVar()
self._vinEntry = Entry(self._dataPaneEntryInfo, textvariable = self._vinVar)
self._vinEntry.grid(row = 4, column = 3)
******************************************************************************************************************************************************************************************************
''' Creates the nested frame for the Data pane'''
self._dataPaneComment = Frame(self, bg = "black")
self._dataPaneComment.grid(row = 2, column = 0)
'''# Label and info field for Comment Box .'''
self._text = "Enter text here. "
self._outputArea = Text(self._dataPaneComment, width = 50, height = 10, wrap = WORD)
self._outputArea.grid(row = 0, column = 0, columnspan = 2)
*********************************************************************************************************************************************************************************************************
''' Creates the nested frame for the Button pane for the Submit'''
self._buttonPane = Frame(self) #this creates a box for the buttons to be placed in one area.
self._buttonPane.grid(row = 3, column = 0)#this gives the button pane a position in the GUI
''' Black and White button '''
self._button1 = Button(self._buttonPane, text = "SUBMIT", command = self._NameEntry)#This creates the button.
self._button1.grid(row = 0, column = 0) #This gives the button a position in the GUI.
********************************************************************************************************************************************************************************************************
def _NameEntry(self):
open("Results.txt", "w").close()
first = self._firstNameEntry.get()
last = self._LastNameEntry.get()
phone = self._phoneNumberEntry.get()
email = self._EmailEntry.get()
address = self._addressEntry.get()
year = self._yearEntry.get()
make = self._makeEntry.get()
model = self._modelEntry.get()
package = self._packageEntry.get()
vin = self._vinEntry.get()
with open("../" + first + " " + last + ".txt", "a") as the_file:
the_file.write("First Name: " + first + "\n" "Last Name: " + last + "\n" "Phone Number: " + phone + "\n" "Email: " + email + "\n"
"Address: " + address + "\n" "Year: " + year + "\n" "Make: " + make + "\n" "Model: " + model + "\n"
"Package: " + package + "\n" "Vin: " + vin + "\n")
'''open("Results.txt", "w").close()
last = self._LastNameEntry.get()
with open("../Results.txt", "a") as the_file:
the_file.write("Last Name: " + last)'''
'''first = self._firstNameEntry.get()
name = open("Results.txt", "w")
name.write("First Name: ".insert(first))
name.close()'''
def main():
'''Instantiate and pop up the window.'''
App().mainloop()
if __name__ == '__main__':
main()
I'm exactly sure on how to upload the gif file with this code.
The error message is telling you what's wrong. If you have already used one geometry manager within a widget you cannot use another.
e.g. - You cannot use both pack and grid within a frame. You must use one or the other.
You could make another widget and then use the seperate geometry manager within this widget but you would have to use the original manager to place it within the master widget.

Python: I am working on a Restaurant tip calculator, I am trying to integrate radio buttons

I need to know how to implement the selected radio button into my calculations. Thanks for any and all help! I'm really not positive what the problem is, my only quest really comes from the "def selection" part. I just don't know what to do there
from Tkinter import *
class App(Tk):
def __init__(self):
Tk.__init__(self)
self.headerFont = ("Times", "16", "italic")
self.title("Restaurant Tipper")
self.addOrigBill()
self.addChooseOne()
self.addPercTip()
self.addRateTip()
self.addOutput()
def addOrigBill(self):
Label(self, text = "Bill Amount",
font = self.headerFont).grid(columnspan = 1)
self.txtBillAmount = Entry(self)
self.txtBillAmount.grid(row = 1, column = 1)
self.txtBillAmount.insert(0,"100.00")
def addChooseOne(self):
Label(self, text = "Pick ONE! Choose your % of Tip or Rate your experience",
font = self.headerFont).grid(row = 2, column = 1)
def addPercTip(self):
Label(self, text = "% of Tip",
font = self.headerFont).grid(row = 3, column = 0)
self.radPercTip1 = Radiobutton(self, text = "15%",
variable = self.percVar, value = .15, command = self.selected)
self.radPercTip2 = Radiobutton(self, text = "17%",
variable = self.percVar, value = .17, command = self.selected)
self.radPercTip3 = Radiobutton(self, text = "20%",
variable = self.percVar, value = .20, command = self.selected)
self.radPercTip1.grid(row = 4, column = 0)
self.radPercTip2.grid(row = 5, column = 0)
self.radPercTip3.grid(row = 6, column = 0)
def selected(self):
float(self.percVar.get())
def addRateTip(self):
Label(self, text = "Tip by rating").grid(row = 3, column = 3)
Label(self, text = "1 being the worst").grid(row = 4, column = 3)
Label(self, text = "10 being the best").grid(row = 5, column = 3)
Label(self, text = "Experience").grid(row = 6, column = 2)
self.txtExperience = Entry(self)
self.txtExperience.grid(row = 6, column = 3)
def addOutput(self):
self.btnCalc = Button(self, text = "Calculate Tip")
self.btnCalc.grid(row = 7, columnspan = 2)
self.btnCalc["command"] = self.calculate
Label(self, text = "Tip").grid(row = 8, column = 1)
self.lblTip = Label(self, bg = "#ffffff", anchor = "w", relief = "ridge")
self.lblTip.grid(row = 8, column = 2, sticky = "we")
Label(self, text = "Total Bill").grid(row = 9, column = 1)
self.lblTotalBill = Label(self, bg = "#ffffff", anchor = "w", relief = "ridge")
self.lblTotalBill.grid(row = 9, column = 2, sticky = "we")
def calculate(self):
bill = float(self.txtBillAmount.get())
percTip = self.percVar
rateTip = int(self.addRateTip.get())
tip = bill * percTip
self.lblTip["text"] = "%.2f" % tip
totalBill = tip + bill
self.lblTotalBill["text"] = "%.2f" % totalBill
if rateTip <= 2:
percTip = .10
elif 3 <= rateTip <= 4:
percTip = .12
elif 5 <= rateTip <= 6:
percTip = .15
elif 7 <= rateTip <= 8:
percTip = .17
elif 9 <= rateTip <= 10:
percTip = .20
else:
self.lblTotalBill["text"] = "Something is wrong"
def main():
app = App()
app.mainloop()
if __name__ == "__main__":
main()
There is no self.percVar in your code. As #wastl said, you need to initialize it.
To do that, you need to use one of the variable classes. Since you are using float type, DoubleVar() would be the best.
def addPercTip(self):
self.percVar = DoubleVar() #this line should be added in your method
Label(self, text = "% of Tip",
font = self.headerFont).grid(row = 3, column = 0)
def selected(self):
print (type(self.percVar.get()))
#which is float, without converting explicitly because of DoubleVar()
print (self.percVar.get())
#this will print what you click
You forgot to intialize the self.percVar variable
Add self.percVar = 0 as the first line of the addPercTip method. That should fix your error.
BTW: For future questions the best thing is to include the error message you get and EXACTLY describe what part of the programm causes what kind of trouble for you

How do I validate an entry widget in python?

I'm creating a GUI using Tkinter that is used to collect information from a user. I need to validate:
First and Last name only contain letters, apostrophes, and dashes
Address
Phone number has the correct number of digits
Valid birthday (Feb 31 doesn't exist and birth year between 1900 and 2014)
Email address contains '#' and '.'
Here is my code:
from tkinter import *
import datetime
class tkwindow:
def __init__(self):
window = Tk() # Create window
window.title("Contact Form") # Give window a title
menubar = Menu(window) # Create menu bar
window.config(menu = menubar) # Display menu bar
'''Using the pulldown menu allows easier access to the menu items instead of using a pop-up menu '''
# Create pulldown menu and add to menu bar
messagesMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "Messages", menu = messagesMenu)
messagesMenu.add_command(label = "Send a Birthday Greeting", command = self.bdayGreeting)
messagesMenu.add_command(label = "Print Address", command = self.printAddress)
# Create another menu option
endMenu = Menu(menubar, tearoff = 0)
menubar.add_cascade(label = "End", menu = endMenu)
endMenu.add_command(label = "Reset Form", command = self.resetForm)
endMenu.add_command(label = "Exit Program", command = window.quit)
# Using Label widget
labelFirst = Label(window, text = "First Name: ").grid(row = 1, column = 1, sticky = E)
labelLast = Label(window, text = "Last Name: ").grid(row = 2, column = 1, sticky = E)
labelAddress = Label(window, text = "Address: ").grid(row = 3, column = 1, sticky = E)
labelPhone = Label(window, text = "Phone Number (8005551234): ").grid(row = 4, column = 1, sticky = E)
labelBday = Label(window, text = "Birthday (MM/DD/YYYY): ").grid(row = 5, column = 1, sticky = E)
labelEmail = Label(window, text = "Email Address (user#domain.com): ").grid(row = 6, column = 1, sticky = E)
# Using Entry widget
self.firstName = StringVar()
entryFirst = Entry(window, textvariable = self.firstName, justify = LEFT).grid(row = 1, column = 2, sticky = W)
self.lastName = StringVar()
entryLast = Entry(window, textvariable = self.lastName, justify = LEFT).grid(row = 2, column = 2, sticky = W)
self.address = StringVar()
entryAddress = Entry(window, textvariable = self.address, justify = LEFT).grid(row = 3, column = 2, sticky = W)
self.phone = StringVar()
entryPhone = Entry(window, textvariable = self.phone, justify = LEFT).grid(row = 4, column = 2, sticky = W)
self.bday = StringVar()
entryBday = Entry(window, textvariable = self.bday, justify = LEFT).grid(row = 5, column = 2, sticky = W)
self.email = StringVar()
entryEmail = Entry(window, textvariable = self.email, justify = LEFT).grid(row = 6, column = 2, sticky = W)
self.errorLblFirst = Label(window, fg = "red")
self.errorLblFirst.grid(row = 1, column = 3)
self.errorLblLast = Label(window, fg = "red")
self.errorLblLast.grid(row = 2, column = 3)
self.errorLblAddress = Label(window, fg = "red")
self.errorLblAddress.grid(row = 3, column = 3)
self.errorLblPhone = Label(window, fg = "red")
self.errorLblPhone.grid(row = 4, column = 3)
self.errorLblBday = Label(window, fg = "red")
self.errorLblBday.grid(row = 5, column = 3)
self.errorLblEmail = Label(window, fg = "red")
self.errorLblEmail.grid(row = 6, column = 3)
# Using Button widget
buttonSubmit = Button(window, text = "Submit", command = self.submit).grid(row = 7, column = 2, sticky = E)
window.mainloop()
def resetForm(self):
self.firstName.set('')
self.errorLblFirst["text"] = ''
self.lastName.set('')
self.errorLblLast["text"] = ''
self.address.set('')
self.errorLblAddress["text"] = ''
self.phone.set('')
self.errorLblPhone["text"] = ''
self.bday.set('')
self.errorLblBday["text"] = ''
self.email.set('')
self.errorLblEmail["text"] = ''
def validFirst(self):
for letter in self.firstName.get():
if not letter.isalpha() and letter not in "'-":
self.errorLblFirst["text"] = " * Letters, apostrophes('), and hypens(-) only"
return False
return True
def validLast(self):
for letter in self.lastName.get():
if not letter.isalpha() and letter not in "'-":
self.errorLblLast["text"] = " * Letters, apostrophes('), and hypens(-) only"
return False
return True
def validAddress(self):
for letter in self.address.get():
if not letter.isalnum() and letter not in "'- .,":
self.errorLblAddress["text"] = " * No special characters"
return False
return True
def validPhone(self):
D = 0
for number in self.phone.get():
if number.isdigit():
D += 1
if D == 10:
return True
else:
self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
return False
return True
def validBday(self):
'''try:
valid_date = datetime.datetime.strptime(str(self.bday), '%m/%d/%Y')
except ValueError:
print('Invalid date!')'''
return True
def validEmail(self):
for letter in self.email.get():
if not letter.isalnum() and letter not in "#.":
self.errorLblEmail["text"] = " * Must have # and ."
return False
return True
def bdayGreeting(self):
if self.validBday() and self.validFirst() == True:
print("Happy Birthday" + self.firstName.get() + "\n" + self.bday.get())
def printAddress(self):
if self.validFirst() and self.validLast() and self.validAddress() == True:
print(self.firstName.get() + " " + self.lastName.get() + "\n" + self.address.get())
def submit(self):
self.validFirst()
self.validLast()
self.validAddress()
self.validPhone()
self.validBday()
self.validEmail()
tkwindow()
I have a couple questions.
Starting from def validFirst(self), how do I validate the different entry fields? I keep getting NameError: name "asdf" is not defined, SyntaxError: unexpected EOF while parsing, and TypeError: 'int' object is not subscriptable when I modify the code and I'm still stuck on validFirst(self).
I have a set of labels in column 3 reserved for error messages: errorLblFirst = Label(window, text = " ", fg = "red").grid(row = 1, column = 3). Is it possible to set it to " * Invalid Entry", fg = "red" when the validation for that entry fails? Is there another way to get error messages to show?
Thanks in advance for the input!
Edit: I updated to my latest code. Most of the validation works now except for validBday and validEmail if you could check it out.
errorLblFirst = Label(...).grid(...)
This way you assign result of grid() to errorLblFirst but grid() always returns None
Always do it this way
errorLblFirst = Label(...)
errorLblFirst.grid(...)
And now you can do (for example)
errorLblFirst["text"] = " * Invalid Entry"
errorLblFirst["fg"] = "red"
EDIT:
You forgot len() in for i in range(first): in validFirst()
And you don't need eval().
(You got the same problem in validPhone())
F = 0
fName = True
first = self.firstName.get() # without eval()
for i in range(len(first)): # len()
if first[i].isdigit():
F += 1
if F > 0:
return False
else:
return fName
return fName
but you could do this shorter
for letter in self.firstName.get():
if letter.isdigit():
return False
return True
if you need only letters (no space, commas, etc.) you could do this
return self.firstName.get().isalpha()
EDIT:
I see First Name can have apostrophes, and dashes
for letter in self.firstName.get():
if not letter.isalpha() and letter not in "'-":
return False
return True
EDIT: problem with self.phone and StringVar
self.phone is StringVar() - not string
but StringVar() has .get() to get string
for number in range(len( self.phone.get() )):
By the way: you can do for loop more pythonic - without range(len())
for char in self.phone.get():
if char.isdigit():
EDIT: problem with validEmail() and validBday()
Email validation needs more if.
For example you could add
email = self.email.get()
if '#' not in email and '.' not in email::
print( 'email needs # and . at the same time')
but '.#' will pass this test :/
Real email validation is more complicated.
See valid email examples: https://fightingforalostcause.net/content/misc/2006/compare-email-regex.php
self.bday is StringVar - use self.bday.get() in place of str(self.bday)
EDIT:
def validPhone(self):
D = 0
for number in self.phone.get():
if number.isdigit():
D += 1
# outside
if D == 10:
return True
else:
self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
return False
return True
or even
def validPhone(self):
# remove previous error message
self.errorLblPhone["text"] = ""
D = 0
for number in self.phone.get():
if number.isdigit():
D += 1
if D != 10:
self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
return False
return True
If number can have only 10 digits (no space, no - , etc):
def validPhone(self):
# remove previous error message
self.errorLblPhone["text"] = ""
D = True
for number in self.phone.get():
if not number.isdigit():
D = False
break
if not D or len(number) != 10:
self.errorLblPhone["text"] = " * Must be 10-digit phone number without spaces"
return False
return True

Categories

Resources