In this part of my Python program, I am taking user inputs from Text widgets and inserting them into a pre-existing SQL Server table. The inputs are validated before then being written to the table, however if I try to delete my newly inserted row it is not there. I opened up SQL Server Management Studio and the data doesn't appear to have actually inserted into the table, despite no error when the query was executed.
I'm using Pyodbc, and having already looked around for answers the most common suggestion was to use conn.commit() however I already have this in place, and it isn't solving the problem.
My code relevant to this issue is below:
def gsap_commit():
teams = ["Arsenal", "Aston Villa", "Brentford", "Brighton", "Burnley", "Chelsea", "Crystal Palace", "Everton", "Leeds", "Leicester", "Liverpool",
"Man City", "Man United", "Newcastle", "Norwich", "Southampton", "Tottenham", "Watford", "West Ham", "Wolves"]
gs_fname = gs_ent1.get("1.0", "end-1c")
gs_sname = gs_ent2.get("1.0", "end-1c")
gs_apdob = gs_ent3.get("1.0", "end-1c")
gs_pos = gs_ent4.get("1.0", "end-1c")
gs_team = gs_ent5.get("1.0", "end-1c")
gs_price = gs_ent6.get("1.0", "end-1c")
if gs_fname.isalpha() == True and gs_sname.isalpha() == True:
if int(gs_apdob[5:7]) <= 12 and int(gs_apdob[8:10]) <= 31:
if gs_pos == "GK" or gs_pos == "DEF" or gs_pos == "MID" or gs_pos == "FWD":
if gs_team in teams:
if int(gs_price) > 4.5 and int(gs_price) < 18:
addplayerquery = "INSERT INTO PlayerList(FirstName, Surname, DOB, Position, Team, Price, InitialPrice, TotalPts, InjuryStatus, DoubtStatus) VALUES (?,?,?,?,?,?,?,0,0,0)"
cursor.execute(addplayerquery, gs_fname, gs_sname, gs_apdob, gs_pos, gs_team, gs_price, gs_price)
conn.commit()
tkMessageBox.showinfo("Add Player Successful", "Successfully added player - {0} {1}".format(gs_fname, gs_sname))
else:
tkMessageBox.showinfo("Add Player Unsuccessful", "The price entered was too anomalous.\nPlease re-enter a suitable price")
else:
tkMessageBox.showwarning("Add Player Unsuccessful", "Please enter a valid team name")
else:
tkMessageBox.showwarning("Add Player Unsuccessful", "Please enter a valid position")
else:
tkMessageBox.showwarning("Add Player Unsuccessful", "Please enter a valid birth date")
else:
tkMessageBox.showwarning("Add Player Unsuccessful", "Please enter a valid name")
def gs_add_player():
gs_ent1.configure(state="normal")
gs_ent2.configure(state="normal")
gs_ent3.configure(state="normal")
gs_ent4.configure(state="normal")
gs_ent5.configure(state="normal")
gs_ent6.configure(state="normal")
gs_ent1.delete("1.0",END)
gs_ent1.insert("1.0", "First Name")
gs_ent1.configure(width=20, bd=1)
gs_ent1.focus()
gs_ent2.delete("1.0",END)
gs_ent2.insert("1.0", "Surname")
gs_ent2.configure(width=20, bd=1)
gs_ent3.delete("1.0",END)
gs_ent3.insert("1.0", "DOB ('YYYY-MM-DD')")
gs_ent3.configure(width=20, bd=1)
gs_ent4.delete("1.0",END)
gs_ent4.insert("1.0", "Position")
gs_ent4.configure(width=8, bd=1)
gs_ent5.delete("1.0",END)
gs_ent5.insert("1.0", "Team")
gs_ent5.configure(width=20, bd=1)
gs_ent6.delete("1.0",END)
gs_ent6.insert("1.0", "Price")
gs_ent6.configure(width=5, bd=1)
gs_confirm_bt.configure(text="Add", command=gsap_commit)
gs_addplr_bt = tk.Button(self, text="Add Player", bg="#0ebf08", fg="white", font=("Segoe UI", 12), command=gs_add_player)
gs_ent1 = tk.Text(self, height=1, width=20, bd=2)
gs_ent2 = tk.Text(self, height=1, width=20, bd=2)
gs_ent3 = tk.Text(self, height=1, width=20, bd=2)
gs_ent4 = tk.Text(self, height=1, width=8, bd=2)
gs_ent5 = tk.Text(self, height=1, width=20, bd=2)
gs_ent6 = tk.Text(self, height=1, width=5, bd=2)
gs_ent1.configure(state="disabled")
gs_ent2.configure(state="disabled")
gs_ent3.configure(state="disabled")
gs_ent4.configure(state="disabled")
gs_ent5.configure(state="disabled")
gs_ent6.configure(state="disabled")
gs_confirm_bt = tk.Button(self, text="Add", fg="white", bg="#38003c", width=10)
gs_addplr_bt.grid(row=6, column=2, columnspan=2, sticky="NSEW", pady=(10,10))
gs_ent1.grid(row=11, column=0)
gs_ent2.grid(row=11, column=1)
gs_ent3.grid(row=11, column=2)
gs_ent4.grid(row=11, column=3)
gs_ent5.grid(row=11, column=4)
gs_ent6.grid(row=11, column=5)
gs_confirm_bt.grid(row=12, column=2, columnspan=2, pady=(20,0))
Here is also the code establishing a connection to SQL Server, declared at the start of the program (different class etc. to code above) in case it is useful:
conn = pyodbc.connect("Driver={SQL Server};"
"Server=DESKTOP-MLKS8CG\SQLEXPRESS;"
"Database=FFProject;"
"Trusted_Connection=yes;")
cursor = conn.cursor()
Could anyone please help me understand why my INSERT statement is not appearing to save? Thanks!
I also faced the same issue, for me restarting SQL server worked fine.
Related
This is my code for a login page with registration form and change password form using tkinter on python. I am unable to center the main display window on my computer screen. This is at the bottom of my code. I am not sure how to fix this. The button formats (e.g. relief styles) also do not work. If there are any issues or suggestions in regards to my code, please do let me know as it would be greatly appreciated!
Edit: Background colour is now shown on display.
'''
import tkinter as tk
from tkinter import messagebox
import sqlite3
import re
# Constants (written in caps)
REGULAR_FONT = ('Georgia', 14)
UNDERLINED_FONT = ('Georgia', 14, 'underline')
SMALL_FONT = ('Georgia', 12)
WINDOW_WIDTH, WINDOW_HEIGHT = 600, 600
# Set numbers as global variables
numbers = set('0123456789')
# Database to save user data
# create a / connect to Database
con = sqlite3.connect('User_Data.db')
# create Cursor
cur = con.cursor()
# create table
cur.execute('''CREATE TABLE IF NOT EXISTS User_Data (
name text,
username text,
gender text,
password varchar,
question text,
answer text
)''')
# commit changes to Database
con.commit()
# close connection
con.close()
class MainDisplay(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
# fill space allocated and expand if needed
container.pack(side='top', fill='both', expand=True)
# set minimum to 0 and priority in container
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
# create dictionary
self.frames = {}
# puts frames (pages) into dictionary
for F in (LoginPage, RegistrationForm, ChangePasswordForm):
# put in container
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky='nsew')
# display login page
self.show(LoginPage)
# create function which shows the chosen frame (page)
def show(self, controller):
frame = self.frames[controller]
frame.tkraise()
class LoginPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
login = tk.Frame(self, bd=1, background='#FFFFFF', relief='solid', padx=20, pady=20)
# Login Questions (Username & Password)
tk.Label(login, text='Username', background='#FFFFFF', font=REGULAR_FONT).grid(row=0, column=0, sticky='w',
padx=10)
tk.Label(login, text='Password', background='#FFFFFF', font=REGULAR_FONT).grid(row=2, column=0, sticky='w',
padx=10)
# Login Answers (User entry)
login_username = tk.Entry(login, font=REGULAR_FONT)
login_password = tk.Entry(login, font=REGULAR_FONT)
login_username.grid(row=1, column=0, padx=10)
login_password.grid(row=3, column=0, padx=10)
# Register Button & Forget Password Button (Redirect)
register_button = tk.Button(login, width=15, text='Register?', font=UNDERLINED_FONT, relief='flat',
command=lambda: controller.show(RegistrationForm))
register_button.grid(row=4, column=0, sticky='w', padx=10)
forgetpassword_button = tk.Button(login, width=15, text='Forget password?', font=UNDERLINED_FONT, relief='flat',
command=lambda: controller.show(ChangePasswordForm))
forgetpassword_button.grid(row=5, column=0, sticky='w', padx=10)
# create function which verifies login
def verify_login():
log_user = login_username.get()
log_password = login_password.get()
# counts which fields have been filled
counter = 0
error = ''
if log_user == '':
error = 'All details must be filled up.'
else:
counter += 1
if log_password == '':
error = 'All details must be filled up.'
else:
counter += 1
# verify login using counter (check if all fields have been filled)
if counter == 2:
try:
# create / connect to Database
con = sqlite3.connect('User_Data.db')
# create Cursor
cur = con.cursor()
# check whether data entered by user matches data in database
cur.execute('SELECT * from User_Data WHERE username = ? AND password = ?', (log_user, log_password))
if cur.fetchall():
# clear entry fields
login_username.delete(0, 'end')
login_password.delete(0, 'end')
# display successful login message
messagebox.showinfo(message='Login was successful.')
else:
messagebox.showerror(
message='Invalid username or password. Please check whether details have been '
'entered correctly and that the account has been registered.')
# commit changes to Database
con.commit()
# close connection
con.close()
except Exception as ep:
messagebox.showerror('', ep)
else:
messagebox.showerror('Error', error)
# Login Button
login_button = tk.Button(login, width=15, text='Login', font=REGULAR_FONT, relief='raised',
command=verify_login)
login_button.grid(row=4, column=1, sticky='e', padx=20, pady=10)
login.place(anchor='center', relx=.5, rely=.5)
class RegistrationForm(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
register = tk.Frame(self, bd=1, background='#FFFFFF', relief='solid', padx=20, pady=20)
# Registration Questions (Name, Username, Gender, Password, Password Confirmation, Security Question and Answer)
tk.Label(register, text='Name', background='#FFFFFF', font=REGULAR_FONT).grid(row=0, column=0, sticky='w',
pady=10)
tk.Label(register, text='Username', background='#FFFFFF', font=REGULAR_FONT).grid(row=1, column=0, sticky='w',
pady=10)
tk.Label(register, text='Gender', background='#FFFFFF', font=REGULAR_FONT).grid(row=2, column=0, sticky='w',
pady=10)
tk.Label(register, text='Password', background='#FFFFFF', font=REGULAR_FONT).grid(row=3, column=0, sticky='w',
pady=10)
tk.Label(register, text='Confirm Password', background='#FFFFFF', font=REGULAR_FONT).grid(row=4, column=0,
sticky='w', pady=10)
tk.Label(register, text='Security Question', background='#FFFFFF', font=REGULAR_FONT).grid(row=5, column=0,
sticky='w', pady=10)
tk.Label(register, text='Security Answer', background='#FFFFFF', font=REGULAR_FONT).grid(row=6, column=0,
sticky='w', pady=10)
# Registration Answers (User Entry)
# user only manually enters Name, Username, Password, Password Confirmation, Security Answer
register_name = tk.Entry(register, font=REGULAR_FONT)
register_username = tk.Entry(register, font=REGULAR_FONT)
register_password = tk.Entry(register, font=REGULAR_FONT)
confirm_password = tk.Entry(register, font=REGULAR_FONT)
security_answer = tk.Entry(register, font=REGULAR_FONT)
register_name.grid(row=0, column=1, pady=10, padx=20)
register_username.grid(row=1, column=1, pady=10, padx=20)
register_password.grid(row=3, column=1, pady=10, padx=20)
confirm_password.grid(row=4, column=1, pady=10, padx=20)
security_answer.grid(row=6, column=1, pady=10, padx=20)
# create function which writes password criteria in entry box
def show_criteria1(t):
register_password.delete(0, 'end')
register_password.insert(0, 'At least 1 number from 0 to 9.')
register_password.bind('<FocusIn>', show_criteria1)
register_password.config(width=20, font=REGULAR_FONT)
def show_criteria2(t):
confirm_password.delete(0, 'end')
confirm_password.insert(0, 'At least 1 number from 0 to 9.')
confirm_password.bind('<FocusIn>', show_criteria2)
confirm_password.config(width=20, font=REGULAR_FONT)
# user chooses Gender
# define variable for Gender Options
var = tk.StringVar()
var.set('Male')
# buttons for Gender Options
register_gender = tk.LabelFrame(register, font=REGULAR_FONT)
answer_male = tk.Radiobutton(register_gender, text='Male', background='#FFFFFF', variable=var,
value='Male', font=SMALL_FONT)
answer_female = tk.Radiobutton(register_gender, text='Female', background='#FFFFFF', variable=var,
value='Female', font=SMALL_FONT)
answer_other = tk.Radiobutton(register_gender, text='Other', background='#FFFFFF', variable=var,
value='Other', font=SMALL_FONT)
register_gender.grid(row=2, column=1, pady=10, padx=20)
answer_male.pack(expand=True, side='left')
answer_female.pack(expand=True, side='left')
answer_other.pack(expand=True, side='left')
# user chooses Security Questions
# list for Security Questions
questions = []
# define variable for Security Questions
variable = tk.StringVar()
# text file of Security Questions
world = open('securityquestions.txt', 'r')
for securityquestions in world:
securityquestions = securityquestions.rstrip('\n')
# add Security Questions to list
questions.append(securityquestions)
variable.set(questions[5])
# dropdown menu for Security Questions
security_question = tk.OptionMenu(register, variable, *questions)
security_question.grid(row=5, column=1)
security_question.config(width=20, font=SMALL_FONT)
# create function to verify registration
def verify_register():
# counts which fields have been filled
counter = 0
error = ''
if register_name.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if register_username.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if var.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if register_password.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if confirm_password.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
# check whether password fulfills the criteria
if re.search('[0-9]', register_password.get()) is None:
error = 'Password must have at least 1 number.'
else:
counter += 1
# check whether password fulfills the criteria
if re.search('[0-9]', confirm_password.get()) is None:
error = 'Password must have at least 1 number.'
else:
counter += 1
# check whether passwords match
if register_password.get() != confirm_password.get():
error = 'Passwords do not match.'
else:
counter += 1
if variable.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if security_answer.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
# verify register using counter (check if all fields have been filled, passwords fulfill criteria and match)
if counter == 10:
try:
# create a / connect to Database
con = sqlite3.connect('User_Data.db')
# create Cursor
cur = con.cursor()
# enter into table
cur.execute('''INSERT INTO User_Data VALUES (:name, :username, :gender,
:password, :question, :answer)''',
{
'name': register_name.get(),
'username': register_username.get(),
'gender': var.get(),
'password': register_password.get(),
'question': variable.get(),
'answer': security_answer.get()
})
# commit changes to Database
con.commit()
# close connection
con.close()
# clear entry fields
register_name.delete(0, 'end')
register_username.delete(0, 'end')
register_password.delete(0, 'end')
confirm_password.delete(0, 'end')
security_answer.delete(0, 'end')
# display successful registration message
messagebox.showinfo(message='Registration was successful.')
# redirect to Login Page
controller.show(LoginPage)
except Exception as e:
messagebox.showerror('', e)
else:
messagebox.showerror('Error', error)
# Register Button
register_button = tk.Button(register, width=10, text='Register', font=REGULAR_FONT, relief='raised',
command=verify_register)
register_button.grid(row=7, column=1, sticky='e', pady=10, padx=20)
register.place(anchor='center', relx=.5, rely=.5)
class ChangePasswordForm(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
password_change = tk.Frame(self, bd=1, background='#FFFFFF', relief='solid', padx=20, pady=20)
# Change Password Form Questions (Username, Security Question, Security Answer, New Password and New Password
# Confirmation)
tk.Label(password_change, text='Username', background='#FFFFFF', font=REGULAR_FONT).grid(row=0,
column=0, sticky='w',
pady=10)
tk.Label(password_change, text='User ID', background='#FFFFFF', font=REGULAR_FONT).grid(row=2,
column=0,
sticky='w',
pady=10)
tk.Label(password_change, text='Security Question', background='#FFFFFF', font=REGULAR_FONT).grid(row=3,
column=0,
sticky='w',
pady=10)
tk.Label(password_change, text='Security Answer', background='#FFFFFF', font=REGULAR_FONT).grid(row=4,
column=0,
sticky='w',
pady=10)
tk.Label(password_change, text='New Password', background='#FFFFFF', font=REGULAR_FONT).grid(row=5,
column=0,
sticky='w',
pady=10)
tk.Label(password_change, text='Confirm New Password', background='#FFFFFF', font=REGULAR_FONT).grid(row=6,
column=0,
sticky='w',
pady=10)
# Change Password Form Answer (User Entry)
# user only manually enters Username, Security Answer, New Password and New Password Confirmation
check_username = tk.Entry(password_change, font=REGULAR_FONT)
user_id = tk.Entry(password_change, font=REGULAR_FONT)
check_securityanswer = tk.Entry(password_change, font=REGULAR_FONT)
new_password = tk.Entry(password_change, font=REGULAR_FONT)
confirm_newpassword = tk.Entry(password_change, font=REGULAR_FONT)
check_username.grid(row=0, column=1, pady=10, padx=20)
user_id.grid(row=2, column=1, pady=10, padx=20)
check_securityanswer.grid(row=4, column=1, pady=10, padx=20)
new_password.grid(row=5, column=1, pady=10, padx=20)
confirm_newpassword.grid(row=6, column=1, pady=10, padx=20)
# create function which finds User ID (oid)
def query():
# create / connect to Database
con = sqlite3.connect('User_Data.db')
# create Cursor
cur = con.cursor()
# Query Database
# print primary key (oid) created by sqlite
username_input = check_username.get()
cur.execute('SELECT *, oid FROM User_Data WHERE username = ?', (username_input,))
user_records = cur.fetchall()
# define variables for print records and find security question
print_records = ''
find_securityquestion = ''
# loop through results
for user_record in user_records:
print_records += str(user_record[0]) + '\t' + str(user_record[1]) + '\t' + str(user_record[6]) + '\n'
find_securityquestion += str(user_record[4])
# display User ID
tk.Label(password_change, text=print_records, font=REGULAR_FONT).grid(row=1, column=1, padx=10, pady=10)
tk.Label(password_change, text=find_securityquestion, font=REGULAR_FONT).grid(row=3, column=1,
padx=10, pady=10)
# commit changes to Database
con.commit()
# close connection
con.close()
# Find User ID Button
find_userid = tk.Button(password_change, width=10, text='Find User ID', font=REGULAR_FONT, relief='raised',
command=query)
find_userid.grid(row=1, column=0, sticky='w', pady=10)
# define function which writes password criteria in entry box
def show_criteria1(t):
new_password.delete(0, 'end')
new_password.insert(0, 'At least 1 number from 0 to 9.')
new_password.bind('<FocusIn>', show_criteria1)
new_password.config(width=20, font=SMALL_FONT)
def show_criteria2(t):
confirm_newpassword.delete(0, 'end')
confirm_newpassword.insert(0, 'At least 1 number from 0 to 9.')
confirm_newpassword.bind('<FocusIn>', show_criteria2)
confirm_newpassword.config(width=20, font=SMALL_FONT)
# create function which updates password record
def change_password():
# define variable for User ID entered by user
userid_input = user_id.get()
# counts which fields have been filled, whether passwords fulfill criteria and match
counter = 0
error = ''
if check_username.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if user_id.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if re.search('[0-9]', user_id.get()) is None:
error = 'Please enter the correct User ID.'
else:
counter += 1
if check_securityanswer.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if new_password.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
if confirm_newpassword.get() == '':
error = 'All details must be filled up.'
else:
counter += 1
# check whether password fulfills the criteria
if re.search('[0-9]', new_password.get()) is None:
error = 'Passwords must have at least 1 number.'
else:
counter += 1
# check whether password fulfills the criteria
if re.search('[0-9]', confirm_newpassword.get()) is None:
error = 'Passwords must have at least 1 number.'
else:
counter += 1
# check whether passwords match
if new_password.get() != confirm_newpassword.get():
error = 'Passwords do not match.'
else:
counter += 1
# verify password change using counter (check if all fields have been filled, user id is correct,
# passwords fulfill criteria and match)
if counter == 9:
try:
# create / connect to Database
con = sqlite3.connect('User_Data.db')
# create Cursor
cur = con.cursor()
# Query Database
# check whether data entered by user matches data in database using User ID input (oid)
cur.execute('SELECT * FROM User_Data WHERE answer = ? AND oid = ?', (check_securityanswer.get(),
userid_input))
if cur.fetchall():
cur.execute('''UPDATE User_Data SET password = :password WHERE oid = :oid''',
{'password': new_password.get(), 'oid': userid_input})
# commit changes to Database
con.commit()
# close connection
con.close()
# clear entry fields
check_username.delete(0, 'end')
user_id.delete(0, 'end')
check_securityanswer.delete(0, 'end')
new_password.delete(0, 'end')
confirm_newpassword.delete(0, 'end')
# message displayed saying password change was successful
messagebox.showinfo(message='Password was changed successfully..')
# redirect to Login Page
controller.show(LoginPage)
# display security answer is incorrect message
else:
messagebox.showerror(message='Security Answer is incorrect.')
except Exception as e:
messagebox.showerror('', e)
else:
messagebox.showerror('Error', error)
# Change Password Button
changepassword_button = tk.Button(password_change, width=15, text='Change Password', font=REGULAR_FONT,
relief='raised', command=change_password)
changepassword_button.grid(row=7, column=1, sticky='e', padx=10, pady=10)
password_change.place(anchor='center', relx=.5, rely=.5)
window = MainDisplay()
window.title('Maze Game')
window.config(background='#E1D4E7')
# Display window at the center of the screen
screen_width = window.winfo_width()
screen_height = window.winfo_height()
window_x = (screen_width / 2) - (WINDOW_WIDTH / 2)
window_y = (screen_height / 2) - (WINDOW_HEIGHT / 2)
window.geometry(f'{WINDOW_WIDTH}x{WINDOW_HEIGHT}+{int(window_x)}+{int(window_y)}')
window.mainloop()
'''
You can use window.eval("tk::PlaceWindow . center") to make the window appear in the center of the screen.
The color code "#E1D4E7" appears to be closer to white, try using any other darker colors to verify if it works
So I want to make a simple inventory system CRUD program. So far, I have been able to make it able to add new items, modify them and delete them. I'm lacking one last thing and that is to be able to search from a treeview which shows all of the items from the sqlite3 database. I wish to have a search box where i could just type in the name of the item and the program will print and select the items searched, which then i could do things such as modify or delete the selected items.
So far my code is:
from tkinter import Tk, Button, PhotoImage, Label, LabelFrame, W, E, N, S, Entry, END, StringVar, Scrollbar, Toplevel
from tkinter import ttk
import sqlite3
class Inventory:
db_filename = 'stock.db'
def __init__(self, root):
self.root = root
self.create_gui()
ttk.style = ttk.Style()
ttk.style.configure('Treeview', font=('helvetica',10))
ttk.style.configure('Treeview.Heading', font=('helvetica', 12, 'bold'))
def execute_db_query(self, query, parameters=()):
with sqlite3.connect(self.db_filename) as conn:
print(conn)
print('You have successfully connected to the Database')
cursor = conn.cursor()
query_result = cursor.execute(query, parameters)
conn.commit()
return query_result
def create_gui(self):
self.create_left_icon()
self.create_label_frame()
self.create_message_area()
self.create_tree_view()
self.create_scrollbar()
self.create_bottom_buttons()
self.view_items()
def create_left_icon(self):
photo = PhotoImage(file='./icons/logo.png')
label = Label(image=photo)
label.image = photo
label.grid(row=0, column=0)
def create_label_frame(self):
labelframe = LabelFrame(self.root, text='Input New Items', bg='sky blue', font='helvetica 10')
labelframe.grid(row=0, column=1, padx=8, pady=8, sticky='ew')
Label(labelframe, text='Name of Item:', bg='sky blue', fg='black').grid(row=1, column=1, sticky=W, pady=2, padx=15)
self.typefield = Entry(labelframe)
self.typefield.grid(row=1, column=2, sticky=W, padx=5, pady=2)
Label(labelframe, text='Stock Card ID:', bg='sky blue', fg='black').grid(row=2, column=1, sticky=W, pady=2, padx=15)
self.cardfield = Entry(labelframe)
self.cardfield.grid(row=2, column=2, sticky=W, padx=5, pady=2)
Label(labelframe, text='Count:', bg='sky blue', fg='black').grid(row=3, column=1, sticky=W, pady=2, padx=15)
self.countfield = Entry(labelframe)
self.countfield.grid(row=3, column=2, sticky=W, padx=5, pady=2)
Button(labelframe, text='Add', command=self.on_add_item_button_clicked, fg='black').grid(row=4, column=2, sticky=E, padx=5, pady=5)
def create_message_area(self):
self.message = Label(text='', fg='red')
self.message.grid(row=3, column=1, sticky=W)
def create_tree_view(self):
self.tree = ttk.Treeview(height=10, columns=('card', 'stock'), style='Treeview')
self.tree.grid(row=6, column=0, columnspan=3)
self.tree.heading('#0', text='Name of Item', anchor=W)
self.tree.heading('card', text='Stock Card ID', anchor=W)
self.tree.heading('stock', text='Count', anchor=W)
def create_scrollbar(self):
self.scrollbar = Scrollbar(orient='vertical', command=self.tree.yview)
self.scrollbar.grid(row=6, column=3, rowspan=10, sticky='sn')
def create_bottom_buttons(self):
Button(text='Delete', command=self.on_delete_selected_button_clicked).grid(row=8, column=0, sticky=W, pady=10, padx=20)
Button(text='Edit Stock', command=self.on_modify_selected_button_clicked).grid(row=8, column=1, sticky=W)
def on_add_item_button_clicked(self):
self.add_new_item()
def on_delete_selected_button_clicked(self):
self.message['text'] = ''
try:
self.tree.item(self.tree.selection())['values'][0]
except IndexError as e:
self.message['text'] = 'Select at least one item to be deleted'
return
self.delete_items()
def on_modify_selected_button_clicked(self):
self.message['text'] = ''
try:
self.tree.item(self.tree.selection())['values'][0]
except:
self.message['text'] = 'Select at least one item to be modified'
return
self.open_modify_window()
def add_new_item(self):
if self.new_items_validated():
query = 'INSERT INTO items_list VALUES(NULL, ?, ?, ?)'
parameters = (self.typefield.get(), self.cardfield.get(), self.countfield.get())
self.execute_db_query(query, parameters)
self.message['text'] = '{} has been added'.format(self.typefield.get())
self.typefield.delete(0, END)
self.cardfield.delete(0, END)
self.countfield.delete(0, END)
self.view_items()
else:
self.message['text'] = 'All entry field must be filled'
self.view_items()
def new_items_validated(self):
return len(self.typefield.get()) !=0 and len(self.cardfield.get()) != 0 and len(self.countfield.get()) != 0
def view_items(self):
items = self.tree.get_children()
for item in items:
self.tree.delete(item)
query = 'SELECT * FROM items_list ORDER BY TipeBarang'
item_entries = self.execute_db_query(query)
for row in item_entries:
self.tree.insert('', 0, text=row[1], values=(row[2], row[3]))
def delete_items(self):
self.message['text']=''
name = self.tree.item(self.tree.selection())['text']
query = 'DELETE FROM items_list WHERE TipeBarang = ?'
self.execute_db_query(query, (name,))
self.message['text'] = '{} has been deleted'.format(name)
self.view_items()
def open_modify_window(self):
name = self.tree.item(self.tree.selection())['text']
old_stock = self.tree.item(self.tree.selection())['values'][1]
self.transient = Toplevel()
self.transient.title('Update Stock')
Label(self.transient, text='Name: ').grid(row=0, column=1)
Entry(self.transient, textvariable=StringVar(
self.transient, value=name), state='readonly').grid(row=0, column=2)
Label(self.transient, text='Old Stock Count: ').grid(row=1, column=1)
Entry(self.transient, textvariable=StringVar(
self.transient, value=old_stock), state='readonly').grid(row=1, column=2)
Label(self.transient, text='New Stock Count: ').grid(row=2, column=1)
new_stock_number_entry_widget = Entry(self.transient)
new_stock_number_entry_widget.grid(row=2, column=2)
Button(self.transient, text='Update Item', command=lambda: self.update_stock(
new_stock_number_entry_widget.get(), old_stock, name)).grid(row=3, column=2, sticky=E)
self.transient.mainloop()
def update_stock(self, newstock, old_stock, name):
query = 'UPDATE items_list SET JumlahStok=? WHERE JumlahStok=? AND TipeBarang=?'
parameters = (newstock, old_stock, name)
self.execute_db_query(query, parameters)
self.transient.destroy()
self.message['text'] = '{} Stock Count has been updated'.format(name)
self.view_items()
if __name__ == "__main__":
root = Tk()
root.title("Inventory System")
root.resizable(width=False, height=False)
application = Inventory(root)
root.mainloop()
Below, I have also attached a screenshot of the program I have made so far. Thank you so much for your help.
Program Screenshot: https://i.stack.imgur.com/1kJch.png
There are a few different ways a search feature can be done here. You can add a search button that creates a Toplevel window and add widgets to it as needed. Or more simply, you can use simpledialog to get text input from the user like so:
queryString = simpledialog.askstring("Search", "Enter item name to search:")
Then pass the resulting queryString to a database function, sanitize it to prevent SQL injection, and SELECT * FROM table WHERE Item = 'queryString'
Then use the data returned from this query to populate your treeview.
def Search():
if SEARCH.get() != "":
tree.delete(*tree.get_children())
conn = sqlite3.connect("db_member.db")
cursor = conn.cursor()
cursor.execute("SELECT * FROM `member` WHERE `firstname` LIKE ? OR `lastname` LIKE ?", ('%'+str(SEARCH.get())+'%', '%'+str(SEARCH.get())+'%'))
fetch = cursor.fetchall()
for data in fetch:
tree.insert('', 'end', values=(data))
cursor.close()
conn.close()
this how you can search from Specific Column in Python with Sqlite3 and Tkinter, you have just to change tow things:
the Name of 'member', which is the Name of your created Table
firstname and lastname are the name of your columns, SEARCH.get() is the variable from the entry box
Hello im having python learning project. I want to insert in GUI two numbers, which are defining range for program to generate random number from.
I am really having problems with calling function with press of the button. And constantly getting error ValueError: invalid literal for int() with base 10: '', when trying to convert string from entry in GUI to int and then inserting them into random.randint.
Thx for Help!
from tkinter import *
import random
root = Tk()
root.title("Generator custom random number")
#function that gets number from entry converts string to int and defines target number in stevilo
def function():
string_answer1 = prvo_stevilo.get()
int1 = int(string_answer1)
string_answer2 = drugo_stevilo.get()
int2 = int(string_answer2)
stevilo = random.randint(int1, int2)
#Defining GUI
navodilo = Label(root, text="Choose custom lower and upper number to chose random number from", width=60)
navodilo2 = Label(root, text="From", width=20, borderwidth=3)
navodilo3 = Label(root, text="To", width=20, borderwidth=3)
prvo_stevilo = Entry(root, width=20, borderwidth=3)
drugo_stevilo = Entry(root, width=20, borderwidth=3)
gumb = Button(root, text="Generate number", width=17, height=2, command=function)
praznavrstica = Label(root, text="")
izpis = Label(root, text="Random number is: ", width=20)
izpis_stevila = Label(root, text="" + stevilo)
#Showcase of gui
navodilo.grid(row=0, column=0, columnspan=1)
navodilo2.grid(row=1, column=0, columnspan=1)
navodilo3.grid(row=3, column=0, columnspan=1)
prvo_stevilo.grid(row=2, column=0, columnspan=1)
drugo_stevilo.grid(row=4, column=0, columnspan=1)
praznavrstica.grid(row=5, column=0, columnspan=1)
gumb.grid(row=6, column=0, columnspan=1)
praznavrstica.grid(row=7, column=0, columnspan=1)
izpis.grid(row=8, column=0, columnspan=1)
izpis_stevila.grid(row=9, column=0, columnspan=1)
#Loop
root.mainloop()
I've noticed few problems with your code. I was able to make it running without too many changes, although probably it is not the best way.
First answer to your question: you are getting this error, because you are trying to change string -> '' to int. It happens because function() is running before you click button.
Another problem:
izpis_stevila = Label(root, text="" + stevilo)
variable 'stevilo' simply doesn't exist before calling function(), so delete it from here.
My proposition for changes:
1)
gumb = Button(root, text="Generate number", width=17, height=2,command = lambda: function())
Without lambda your function will run no matter of state of your button.
2)
first = IntVar(root, value=0)
second = IntVar(root, value=1)
prvo_stevilo = Entry(root, width=20, borderwidth=3, textvariable=first)
drugo_stevilo = Entry(root, width=20, borderwidth=3, textvariable=second)
If you run function without any values in your entry you will get error. This change allows you to put default value for your entry widgets.
3)
def function():
if prvo_stevilo.get() == '' or drugo_stevilo.get() =='':
return
else:
string_answer1 = prvo_stevilo.get()
int1 = int(string_answer1)
string_answer2 = drugo_stevilo.get()
int2 = int(string_answer2)
stevilo = random.randint(int1, int2)
izpis_stevila = Label(root, text=str(stevilo))
izpis_stevila.grid(row=9, column=0)
Firstly check if your entry is not empty.
Secondly update label, also remeber about changing int to string here text=str(stevilo).
I have been making a program that responds to a user input. When I run it my code doesn't insert the response into the text widget. I get the error:
TypeError: insert() missing 1 required positional argument: 'chars'
My code is:
global stuff
stuff = open("Dictionary.txt", "r")
global contents
contents = stuff.read()
stuff.close()
from tkinter import *
dictionary = {"chungus": "Come at me chungus ... you wanna go?",
"hi": "It's good to see you!", "bot": "No - you're the BOT"}
def output():
TT = entry.get()
text.delete(0.0, END)
try:
meaning = dictionary[TT]
except:
meaning = "We do not have a reply for this yet..."
text.insert(meaning)
def words():
TT = (contents)
text.delete(0.0, END)
meaning = (TT)
text.insert(END, meaning)
global window
window = Tk()
window.title("WFR")
label1 = Label(window, text="Enter stuff for reply (No caps): ")
label1.grid(row=0, column=0, sticky=W)
entry = Entry(window, width=35, bg="light green")
entry.grid(row=1, column=0, sticky=W)
button1 = Button(window, text="SUBMIT", width=8, command=output)
button1.grid(row=3, column=0, sticky=W)
text = Text(window, width=60, height=20, wrap=WORD, background="yellow")
text.grid(row=2, column=0, sticky=W)
menubar = Menu(window)
firstmenu = Menu(menubar, tearoff=0)
firstmenu.add_command(label="Type What?", command=words)
menubar.add_cascade(label="Options", menu=firstmenu)
window.config(menu=menubar)
window.mainloop()
Have I missed something?
This is something quite simple to answer. In your code you have written text.insert(END, meaning), earlier in a different area you have typed text.insert(meaning). I think this is simply you missing something as you type your code. Try to copy the correct version of code (with the END, before it) in the line where you are getting your issue. Also, may I suggest adding comments to your code as it makes it a lot easier to see where the issue is.
I am pretty new to Python, but for a team design project I need to create a code to input information into a Tkinter window that is connected to a mysql table and update that table accordingly. If the same ID is inputted again it should update the quantity +1 :
from Tkinter import*
import tkMessageBox
import tkFont
import mysql.connector
import time
def AddItem():
print "Added Item"
print "ID:" + ID.get()
print "Item Name:" + ItemName.get()
print "Price Per Item:" + PricePerItem.get()
print "Manufacturer:" + Manufacturer.get()
The s = INSERT INTO inventory... is throwing me for a loop, I can input the information into the Tkinter window but when I select the Add Item button, this error shows up:
ProgrammingError: Failed processing format-parameters; 'MySQLConverter' object has no attribute '_entry_to_mysql'
cnx = mysql.connector.connect(user='root',password='cj92cj',
database='INVENTORY', use_unicode=False)
s = "INSERT INTO inventory (ID, Manufacturer, ItemName, PricePerItem, Quantity) VALUES({},{},{},{},1) ON DUPLICATE KEY UPDATE Quantity= Quantity + 1, Manufacturer = VALUES(Manufacturer), ItemName = VALUES(ItemName), PricePerItem = VALUES(PricePerItem);".format(ID.get(),Manufacturer.get(),ItemName.get(),PricePerItem.get())
print ID.get()
print s
cursor = cnx.cursor()
cursor.execute(s, (ID, Manufacturer, ItemName, PricePerItem, Quantity))
cursor.close()
cnx.commit()
cnx.close()
def ClearEntries():
ItemName.delete(0,END)
PricePerItem.delete(0,END)
Manufacturer.delete(0,END)
I have been trying all sorts of things with "s" for hours and hours but I am having trouble figuring out the right syntax to use.
Below is the Tkinter Window code if that helps at all.
def InformationInput():
BigFont=tkFont.Font(family="Arial", size=14, weight="bold")
root.title("Enter Item Information")
root.geometry("1000x400")
root.bind("<Return>", lambda event: AddItem())
lbl1 = Label(root, text="ID:")
lbl2 = Label(root, text="Item Name:")
lbl3 = Label(root, text="Price Per Item:")
lbl4 = Label(root, text="Manufacturer:")
lbl9 = Label(root, text="Enter Item Information", height=3, fg="red", font=BigFont)
global ID, ItemName, PricePerItem, Manufacturer
ID = Entry(root, width=25, textvariable=ID)
ItemName = Entry(root, width=20, textvariable=ItemName)
PricePerItem = Entry(root, width=10, textvariable=PricePerItem)
Manufacturer = Entry(root, width=25, textvariable=Manufacturer)
button1 = Button(root, text="Add Item", command=AddItem, width=15)
button2 = Button(root, text="Clear Entries", command=ClearEntries, width=15)
button3 = Button(root, text="Exit", command=root.destroy, width=15)
lbl9.grid(column=2, row=1, columnspan=5)
lbl1.grid(column = 1, row = 4, sticky="nw")
ID.grid(column = 2, row = 4, sticky="nw")
lbl2.grid(column = 3, row = 4)
ItemName.grid(column = 4, row = 4)
lbl3.grid(column = 5, row = 4)
PricePerItem.grid(column = 6, row = 4, sticky="w")
lbl4.grid(column = 3, row = 10)
Manufacturer.grid(column = 4, row = 10)
button1.grid(column=3, row=15, sticky="e", pady=20)
button2.grid(column=4, row=15)
button3.grid(column=5, row=15, sticky="w")
root = Tk()
ID = IntVar()
ItemName = StringVar()
PricePerItem = IntVar()
Manufacturer = StringVar()
Quantity = IntVar()
InformationInput()
root.mainloop()
You have to use parameter marks in your query or your database driver, in this case MySQL Connector/Python, will through an error. Also, you have to pass values which can be converted. MySQLConverter does not know how to convert entry-objects, so it tells you it can't convert it (although it can be a bit more explicit).
Here is an example (simplified):
s = ("INSERT INTO inventory (ID, Manufacturer, ItemName, PricePerItem, Quantity) "
"VALUES (%s, %s, %s, %s, %s) ON DUP..")
cursor = cnx.cursor()
cursor.execute(s, (ID.get(), Manufacturer.get(), ItemName.get(),
PricePerItem.get(), Quantity.get()))
I took the liberty opening a bug report to improve the error message.
Other remark: I don't think you need to give the ID when inserting? Usually that is an AUTO_INCREMENT.