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
Related
May i know where and how do i need to do. I want to add a checkbox in every row and when it checked, the button of update or delete will only effect to the checked row.
I am new in python and currently i'm doing this for my project gui, is that anyone can help or if any suggestion you're welcome. Thanks
Below is my code:
from tkinter import *
from tkinter import messagebox
import mysql.connector
win = Tk()
win.title("Admin Signup")
win.geometry("750x400+300+90")
frame1 = Frame(win)
frame1.pack(side = TOP, fill=X)
frame2 = Frame(win)
frame2.pack(side = TOP, fill=X)
frame3 = Frame(win)
frame3.pack(side = TOP, padx = 10, pady=15)
frame4 = Frame(win)
frame4.pack(side = TOP, padx = 10)
frame5 = Frame(win)
frame5.pack(side = LEFT, padx = 10)
lbl_title = Label(frame1, text = "User List", font = ("BOLD 20"))
lbl_title.pack(side = TOP, anchor = "w", padx = 20, pady = 20)
btn_register = Button(frame2, text = "Register User")
btn_register.pack(side = TOP, anchor = "e", padx=20)
lbl01 = Label(frame3, text="Username", width=17, anchor="w", relief="raised")
lbl01.grid(row=0, column=0)
lbl02 = Label(frame3, text="Password", width=17, anchor="w", relief="raised")
lbl02.grid(row=0, column=1)
lbl03 = Label(frame3, text="Full Name", width=17, anchor="w", relief="raised")
lbl03.grid(row=0, column=2)
lbl04 = Label(frame3, text="Ic Number", width=17, anchor="w", relief="raised")
lbl04.grid(row=0, column=3)
lbl05 = Label(frame3, text="Staff Id", width=17, anchor="w", relief="raised")
lbl05.grid(row=0, column=4)
mydb = mysql.connector.connect(
host = "localhost",
user = "username",
password = "password",
database = "adminacc"
)
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM acc")
i = 0
for details in mycursor:
for j in range(len(details)):
e = Entry(frame4, width=17, relief=SUNKEN)
e.grid(row=i, column=j)
e.insert(END, details[j])
e.config(state=DISABLED, disabledforeground="blue")
i = i+1
btn_update = Button(frame5, text = "Update")
btn_update.grid(row=0, column=0, padx=15)
btn_delete = Button(frame5, text = "Delete")
btn_delete.grid(row=0, column=1)
win.mainloop()
Since every row behaves the same, suggest to use a class to encapsulate the behavior:
class AccountInfo:
def __init__(self, parent, details, row):
self.entries = []
# create entry box for each item in 'details'
for col, item in enumerate(details):
e = Entry(parent, width=17, relief=SUNKEN, disabledforeground='blue', bd=2)
e.grid(row=row, column=col)
e.insert(END, item)
e.config(state=DISABLED)
self.entries.append(e)
# create the checkbutton to select/deselect current row
self.var = BooleanVar()
Checkbutton(parent, variable=self.var, command=self.state_changed).grid(row=row, column=col+1)
def state_changed(self):
state = NORMAL if self.selected else DISABLED
# enable/disable entries except username
for e in self.entries[1:]:
e.config(state=state)
#property
def selected(self):
return self.var.get()
#property
def values(self):
return tuple(x.get() for x in self.entries)
Then using the class to create the required rows for each record retrieved from database:
mycursor.execute("SELECT * FROM acc")
accounts = [] # used to store the rows (accounts)
for row, details in enumerate(mycursor):
acc = AccountInfo(frame4, details, row)
accounts.append(acc)
The saved accounts can then be used in the callbacks of Update and Delete buttons:
def update_accounts():
for acc in accounts:
if acc.selected:
print(acc.values)
# do whatever you want on this selected account
btn_update = Button(frame5, text="Update", command=update_accounts)
Same logic on Delete button.
Note that you can modify the AccountInfo class to add functionalities that suit what you need.
i am new in this community, i am trying to lear python (my version is 3.7 for windows 10)
i have created this program (i will attach the code below) with python / Tkinter
here is where i am stuck:
When the user push "Submit" button, i need to check if the entry box "Assignment number" (if you launch the program, it is on the top of the GUI) already exist on my sqlite3 table before inserting all the data that the user submitted will be stored in the database
Basically i need that each survey submitted have a unique Assignment number
If you could help would be great (haven't sleep in a week)
Thank you in advance for all your help
import backend
import csv
from backend import write_to_csv
import os
from Send_email_gui import send_email
from backend import check_assignment
def add_entry_command():
#check_assignment_no.check_assignment(assignment_no_text.get())
if check_assignment(assignment_no_text.get())== 0:
backend.insert(client_code_text.get(), client_name_text.get(), assignment_no_text.get(), accountant_text.get(), year_end_text.get(), file_presentation_text.get(), quality_of_job_processed_text.get(), queries_text.get(), indexing_text.get(), final_reports_text.get(), documents_handling_text.get(), meeting_deadlines_text.get(), communication_text.get(), analytical_review_text.get(), overall_job_text.get(), suggestion_text.get())
send_email(accountant_text, client_code_text, client_name_text, assignment_no_text, year_end_text, file_presentation_text, quality_of_job_processed_text, queries_text, indexing_text, final_reports_text, documents_handling_text, meeting_deadlines_text, communication_text, analytical_review_text, overall_job_text, suggestion_text)
messagebox.showinfo('Confirmation', 'Thank you for your submission, click ok and close')
else:
messagebox.showinfo('Assignment number used', 'Assignment number already used, please check again and submit')
def __init__(self, assignment_no_, accountant_, year_end_, client_code_, client_name_, file_presentation_, quality_of_job_processed_, queries_,
indexing_, final_reports_, documents_handling_, meeting_deadlines_, communication_, analytical_review_, overall_rate_, suggestion_):
self.assignment_no_=assignment_no_
self.accountant_=accountant_
self.year_end_=year_end_
sel.client_code_=client_code_
self.client_name_=client_name_
self.file_presentation_=file_presentation_
self.quality_job_=quality_of_job_processed_
self.queries_assumptions_=queries_
self.indexing_cross_ref_=indexing_
self.final_reports_=final_reports_
self.doc_handling_=documents_handling_
self.meet_deadlines_=meeting_deadlines_
self.communi_=communication_
self.analytical_rev_=analytical_review_
self.overall_rate_=overall_rate_
self.suggestion_box_=suggestion_
window=Tk()
"""
Center the window of the program
"""
# Gets the requested values of the height and widht.
windowWidth = window.winfo_reqwidth()
windowHeight = window.winfo_reqheight()
#print("Width",windowWidth,"Height",windowHeight)
# Gets both half the screen width/height and window width/height
positionRight = int(window.winfo_screenwidth()/6 - windowWidth/6)
positionDown = int(window.winfo_screenheight()/6 - windowHeight/6)
# Positions the window in the center of the page.
window.geometry("+{}+{}".format(positionRight, positionDown))
"""
Top data entry level
TO DO - build function to return client name directly from Iris database - build button
"""
label_title=Label(window, text="Global Infosys feedback collector", height=3, fg="blue", font=(20))
label_title.grid(row=0, column=2)
l1=Label(window, text="Client code")
l1.grid(row=4, column=1, sticky='E')
l2=Label(window, text="Client name")
l2.grid(row=4, column=3, sticky='E')
l3=Label(window, text="Assignment no:")
l3.grid(row=5, column=1, sticky='E')
l4=Label(window, text="Accountant:")
l4.grid(row=6, column=1, sticky='E')
l5=Label(window, text="Year end:")
l5.grid(row=7, column=1, sticky='E')
"""
Second and third titles - form beginning
"""
label_second_title=Label(window, text="Scoring Referance (enter only 1 number):", height=3, fg="blue")
label_second_title.grid(row=8, column=1, columnspan=2, sticky=W)
label_third_title=Label(window, text="Excellent: 10 | Good: 9 - 8 | Avarage: 7 - 6 | Poor: 0 - 5", height=3, fg="blue")
label_third_title.grid(row=9, column=1, columnspan=2, sticky=W)
empty_label=Label(window, text=" ", width=15)
empty_label.grid(row=9, column=0)
second_empty_label=Label(window, text=" ", width=15)
second_empty_label.grid(row=4, column=6)
#third_empty_label=Label(window, text="View Entry", height=3)
#third_empty_label.grid(row=26, column=1)
"""
Form level labels
"""
l6=Label(window, text="File presentation:")
l6.grid(row=10, column=1, sticky='E')
l7=Label(window, text="Quality of job processing")
l7.grid(row=11, column=1, sticky='E')
l8=Label(window, text="Queries and assumptions:")
l8.grid(row=12, column=1, sticky='E')
l9=Label(window, text="Indexing and cross referencing:")
l9.grid(row=13, column=1, sticky='E')
l10=Label(window, text="Final reports (draft accounts):")
l10.grid(row=14, column=1, sticky='E')
l11=Label(window, text="Documents handling / usage:")
l11.grid(row=15, column=1)
l12=Label(window, text="Meeting deadlines:")
l12.grid(row=16, column=1, sticky='E')
l13=Label(window, text="Communication:")
l13.grid(row=17, column=1, sticky='E')
l14=Label(window, text="Analytical review:")
l14.grid(row=18, column=1, sticky='E')
l15=Label(window, text="Overall Job rating:")
l15.grid(row=19, column=1, sticky='E')
l16=Label(window, text="Suggestion / Review:")
l16.grid(row=20, column=1, sticky='E')
l25=Label(window, text="# A production of Shehan H.", fg="red")
l25.grid(row=30, column=6, sticky='E')
"""
Entry boxes top
"""
client_code_text=StringVar()
e1=Entry(window, textvariable=client_code_text)
e1.grid(row=4, column=2)
client_name_text=StringVar()
e2=Entry(window, textvariable=client_name_text)
e2.grid(row=4, column=4)
assignment_no_text=StringVar()
e3=Entry(window, textvariable=assignment_no_text)
e3.grid(row=5, column=2)
accountant_text=StringVar()
e4=Entry(window, textvariable=accountant_text)
e4.grid(row=6, column=2)
year_end_text=StringVar()
e5=Entry(window, textvariable=year_end_text)
e5.grid(row=7, column=2)
"""
Entry boxes form level
"""
file_presentation_text=StringVar()
e6=Entry(window, textvariable=file_presentation_text)
e6.grid(row=10, column=2)
quality_of_job_processed_text=StringVar()
e7=Entry(window, textvariable=quality_of_job_processed_text)
e7.grid(row=11, column=2)
queries_text=StringVar()
e8=Entry(window, textvariable=queries_text)
e8.grid(row=12, column=2)
indexing_text=StringVar()
e9=Entry(window, textvariable=indexing_text)
e9.grid(row=13, column=2)
final_reports_text=StringVar()
e10=Entry(window, textvariable=final_reports_text)
e10.grid(row=14, column=2)
documents_handling_text=StringVar()
e11=Entry(window, textvariable=documents_handling_text)
e11.grid(row=15, column=2)
meeting_deadlines_text=StringVar()
e12=Entry(window, textvariable=meeting_deadlines_text)
e12.grid(row=16, column=2)
communication_text=StringVar()
e13=Entry(window, textvariable=communication_text)
e13.grid(row=17, column=2)
analytical_review_text=StringVar()
e14=Entry(window, textvariable=analytical_review_text)
e14.grid(row=18, column=2)
overall_job_text=StringVar()
e15=Entry(window, textvariable=overall_job_text)
e15.grid(row=19, column=2)
suggestion_text=StringVar()
e16=Entry(window, textvariable=suggestion_text, width=50)
e16.grid(row=20, column=2, padx=5,pady=10,ipady=3)
"""
Buttons
"""
b1=Button(window, text="Submit to GI", width=12, command=add_entry_command)
b1.grid(row=25, column=2)
b2=Button(window, text="Export report", width=12, command=write_to_csv)
b2.grid(row=25, column=3)
b3=Button(window, text="Connect client", width=12)
b3.grid(row=4, column=5)
"""
List box to view results
Maight be deleted and changed with popup to confirm
list1=Listbox(window, height=1, width=70)
list1.grid(row=26, column=2)
"""
window.mainloop()
and this is the backend module
import sqlite3
import csv
import os
from tkinter import messagebox
from tkinter import *
def connect():
conn=sqlite3.connect("lite.db")
cur=conn.cursor()
cur.execute("CREATE TABLE IF NOT EXISTS gi_store (id INTEGER PRIMARY KEY, client_code_ text, client_name_ text, assignment_no_ text, accountant_ text, year_end_ text, file_presentation_ integer, quality_of_job_processed_ integer, queries_ integer, indexing_ integer, final_reports_ integer, documents_handling_ integer, meeting_deadlines_ integer, communication_ integer, analytical_review_ integer, overall_job_ integer, suggestion_ text)")
conn.commit()
conn.close()
def insert(client_code_, client_name_, assignment_no_, accountant_, year_end_, file_presentation_, quality_of_job_processed_, queries_, indexing_, final_reports_, documents_handling_, meeting_deadlines_, communication_, analytical_review_, overall_job_, suggestion_):
conn=sqlite3.connect("lite.db")
cur=conn.cursor()
cur.execute("INSERT INTO gi_store VALUES(NULL, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (client_code_, client_name_, assignment_no_, accountant_, year_end_, file_presentation_, quality_of_job_processed_, queries_, indexing_, final_reports_, documents_handling_, meeting_deadlines_, communication_, analytical_review_, overall_job_, suggestion_))
conn.commit()
conn.close()
def view():
conn=sqlite3.connect("lite.db")
cur=conn.cursor()
cur.execute("SELECT * FROM gi_store")
rows=cur.fetchall()
conn.close()
return rows
def write_to_csv():
conn=sqlite3.connect("lite.db")
cur=conn.cursor()
cur.execute("SELECT * FROM gi_store")
csvWriter = csv.writer(open("output.csv", "w", newline=''))
rows = cur.fetchall()
csvWriter.writerow(["ID", "Client Code", "Client Name", "Assignment number", "Accountant", "Year End", "File Presentation", "Quality of job processed", "Queries", "Indexing", "Final reports", "Doc. handling", "Meeting deadlines", "Communication", "Analytical review", "Overall rate", "Suggestion box"])
for row in rows:
# do your stuff
csvWriter.writerow(row)
conn.close()
def check_assignment(assignment_no_):
conn=sqlite3.connect("lite.db")
cur=conn.cursor()
control_assignment = cur.execute("SELECT * FROM gi_store WHERE assignment_no_ = ?", (assignment_no_,))
control_assignment_row=cur.fetchone()
conn.close()
return control_assignment_row
connect()
#print(check_assignment(assignment_no_text="2"))
Your functions check_assignment() returns row with assignment number or None but you compare with 0. You should compare with None
if check_assignment(assignment_no_text.get()) is None:
when i click on each of the items in listbox, a text is printed which comes from db in the Textbox widget of my app. i want to be able to do exactly that also with my button. I mean, when user searches the word in entrybox and the list lowers down to 1 item, i want to be able to select that item with 3 ways (clicking on it in the list, clicking on my button, pressing the Return key on my keyboard). now clicking works. how should i config the button event in enter_meaning function?
import sqlite3 as sqlite
import tkinter as tk
from tkinter import ttk
# GUI Widgets
class EsperantoDict:
def __init__(self, master):
self.search_var = tk.StringVar()
self.search_var.trace("w", lambda name, index, mode: self.update_list())
self.frame_header = ttk.Frame(master, relief=tk.FLAT)
self.frame_header.config(style="TFrame")
self.frame_header.pack(side=tk.TOP, padx=5, pady=5)
ttk.Label(self.frame_header, image=self.small_logo).grid(row=0, column=0, stick="ne", padx=5, pady=5, rowspan=2)
ttk.Label(self.frame_header, text='EsperantoDict', font=('Arial', 18, 'bold')).grid(row=0, column=1)
self.frame_content = ttk.Frame(master)
self.frame_content.config(style="TFrame")
self.frame_content.pack()
self.entry_search = ttk.Entry(self.frame_content, textvariable=self.search_var, width=30)
self.entry_search.bind('<FocusIn>', self.entry_delete)
self.entry_search.bind('<FocusOut>', self.entry_insert)
self.entry_search.grid(row=0, column=0, padx=5)
self.entry_search.focus()
self.entry_search.bind("<KeyRelease>", self.edit_input)
self.button_search = ttk.Button(self.frame_content, text=u"Serĉu", command=self.enter_meaning)
self.photo_search = tk.PhotoImage(file=r'C:\EsperantoDict\search.png')
self.small_photo_search = self.photo_search.subsample(3, 3)
self.button_search.config(image=self.small_photo_search, compound=tk.LEFT, style="TButton")
self.button_search.grid(row=0, column=2, columnspan=1, sticky='nw', padx=5)
self.button_search.bind('<Return>')
self.listbox = tk.Listbox(self.frame_content, height=30, width=30)
self.listbox.grid(row=1, column=0, padx=5)
self.scrollbar = ttk.Scrollbar(self.frame_content, orient=tk.VERTICAL, command=self.listbox.yview)
self.scrollbar.grid(row=1, column=1, sticky='nsw')
self.listbox.config(yscrollcommand=self.scrollbar.set)
self.listbox.bind('<<ListboxSelect>>', self.enter_meaning)
self.textbox = tk.Text(self.frame_content, relief=tk.GROOVE, width=60, height=30, borderwidth=2)
self.textbox.config(wrap='word')
self.textbox.grid(row=1, column=2, sticky='w', padx=5)
# SQLite
self.db = sqlite.connect(r'C:\EsperantoDict\test.db')
self.cur = self.db.cursor()
self.cur.execute("SELECT Esperanto FROM Words ORDER BY Esperanto")
for row in self.cur:
self.listbox.insert(tk.END, row)
self.update_list()
def update_list(self):
self.listbox.delete(0, tk.END)
search_term = self.search_var.get().lower()
if search_term == 'type to search':
search_term = ''
self.cur.execute("SELECT Esperanto FROM Words WHERE LOWER(Esperanto) LIKE ? ORDER BY Esperanto",
('%' + search_term + '%',))
for row in self.cur:
item = row[0]
self.listbox.insert(tk.END, item)
for row in range(0, self.listbox.size(), 2):
self.listbox.itemconfigure(row, background="#f0f0ff")
def edit_input(self, tag):
word_to_esp = {'gx': 'ĝ', 'cx': 'ĉ', 'hx': 'ĥ', 'jx': 'ĵ', 'ux': 'ŭ', 'sx': 'ŝ'}
user_input = self.entry_search.get()
user_input = user_input.lower()
for i in word_to_esp:
if user_input.__contains__(i):
a = user_input.replace(i, word_to_esp[i])
return self.search_var.set(a)
def enter_meaning(self, tag=None):
index = self.listbox.curselection()
esperanto = self.listbox.get(index)
results = self.cur.execute("SELECT English FROM Words WHERE Esperanto = ?", (esperanto,))
for row in results:
self.textbox.delete(1.0, tk.END)
self.textbox.insert(tk.END, row[0])
def entry_delete(self, tag):
if self.entry_search.get():
self.entry_search.delete(0, tk.END)
self.textbox.delete(1.0, tk.END)
return None
def entry_insert(self, tag):
if self.entry_search.get() == '':
self.entry_search.insert(0, "Type to Search")
return None
def main():
root = tk.Tk()
EsperantoDict(root)
root.mainloop()
if __name__ == '__main__': main()
# db tbl name: Words
# db first field name: Esperanto
# db second field name: English
I'm pretty new to Pyton.
So I'm trying to make a gui that displays multiple user inputs. I've managed to do it with two inputs (text and number):
class Product:
db_name = 'mydatabase.db'
def __init__(self, wind):
self.wind=wind
self.wind.title('Date pacienti')
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='Last name:').grid(row=2, column=1)
self.last = Entry(frame)
self.last.grid(row=2, column =2)
Label(frame, text = 'Age:').grid(row=3, column=1)
self.age=Entry(frame)
self.age.grid(row=3, column=2)
Label(frame, text = 'Something else:').grid(row=4, column=1)
self.else=Entry(frame)
self.else.grid(row=4, column=2)
ttk.Button(frame, text='Add record', command = self.adding).grid (row=5,column=2)
self.message=Label(text='', fg='red')
self.message.grid(row=3, column=0)
self.tree = ttk.Treeview (height=10, columns=2)
self.tree.grid(row=7, column=0, columnspan=2)
self.tree.heading('#0',text = 'Name', anchor=W)
self.tree.heading(2, text='Last name', anchor=W)
self.tree.heading(3, text = 'Age', anchor=W)
self.tree.heading(4, text='Something else', anchor=W)
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 pacienti ORDER BY nume DESC'
db_rows = self.run_query (query)
for row in db_rows:
self.tree.insert('', 0, text = row[1], value = row[3])
I want to add more text fields for the user to input (e.g. text = row[2], row[4]... ).
How would I go about it?
I am pulling a variable from the user when they select one of the radio buttons I provide them. Each radio button variable is set as an actual server I can normally connect to using MsSql.
My below code has a !!!!!!!!!!!!! MY EXAMPLE !!!!!!!!!!!!!!!!!! listed next to the spot I am trying to figure out.
I get a connection error when I use pypyodbc.connect ('Server=serverName;'), but I know it works if I get rid of the radio button variable and enter the actual server name.
Any ideas?
#! /usr/bin/python
import os
import pypyodbc
import tkinter
from tkinter import ttk
class Adder(ttk.Frame):
"""The adders gui and functions."""
def __init__(self, parent, *args, **kwargs):
ttk.Frame.__init__(self, parent, *args, **kwargs)
self.root = parent
self.init_gui()
def on_quit(self):
"""Exits program."""
quit()
def calculate(self):
serverName = str(self.selectedTown.get()) #! !!!!!!!!!!!!! MY EXAMPLE !!!!!!!!!!!!!!!!!!
word1 = str(self.workstation1_entry.get())
# num2 = int(self.localid2_entry.get()) # This will be entered in a later statement where user can enter LocationID
# if str(self.selectedTown.get()) in str(self.selectedTown.get()):
connection = pypyodbc.connect('Driver={SQL Server};' #! !!!!!!!!!!!!! MY EXAMPLE !!!!!!!!!!!!!!!!!!
'Server=serverName;'
'Database=mydatabase;'
'Trusted_Connection=yes;')
cursor = connection.cursor()
SQLCommand = ("SELECT Name, Location_ID "
"FROM dbo.PB_Location "
"WHERE Name = ?")
Values = [word1]
cursor.execute(SQLCommand,Values)
results = cursor.fetchone()
if results:
self.answer_label['text'] = str(results[1]) # displays answer
connection.close()
else:
self.answer_label['text'] = "Invalid"
connection.close()
def init_gui(self):
"""Builds GUI."""
self.root.title('ID Lookup')
self.root.option_add('*tearOff', 'FALSE')
self.grid(column=0, row=0, sticky='nsew')
self.menubar = tkinter.Menu(self.root)
self.menu_file = tkinter.Menu(self.menubar)
self.menu_file.add_command(label='Exit', command=self.on_quit)
self.menu_edit = tkinter.Menu(self.menubar)
self.menubar.add_cascade(menu=self.menu_file, label='File')
self.menubar.add_cascade(menu=self.menu_edit, label='Edit')
self.root.config(menu=self.menubar)
self.workstation1_entry = ttk.Entry(self, width=5)
self.workstation1_entry.grid(column=1, row = 2)
self.localid2_entry = ttk.Entry(self, width=5)
self.localid2_entry.grid(column=3, row=2)
self.calc_button = ttk.Button(self, text='Submit',
command=self.calculate)
self.calc_button.grid(column=0, row=3, columnspan=4)
self.answer_frame = ttk.LabelFrame(self, text='Answer',
height=100)
self.answer_frame.grid(column=0, row=4, columnspan=4, sticky='nesw')
self.answer_label = ttk.Label(self.answer_frame, text='')
self.answer_label.grid(column=0, row=0)
self.selectedTown = tkinter.StringVar()
self.selectedTown.set('b1') # make it where the top radio button is selected by default
self.b1 = ttk.Radiobutton(self, text='Texas', value='1srvodbx', variable=self.selectedTown).grid(sticky='W', column=0,row=6, columnspan=1) # sticky W to align everything to left
self.b2 = ttk.Radiobutton(self, text='Oklahoma', value='2srvodbx', variable=self.selectedTown).grid(sticky='W', column=0,row=7, columnspan=1)
self.b3 = ttk.Radiobutton(self, text='Idaho', value='3srvodbx', variable=self.selectedTown).grid(sticky='W', column=0,row=8, columnspan=1)
self.selectedTown.get()
# Labels that remain constant throughout execution.
ttk.Label(self, text='Location ID Finder').grid(column=0, row=0,
columnspan=4)
ttk.Label(self, text='Name').grid(column=0, row=2,
sticky='w')
ttk.Label(self, text='Location ID').grid(column=2, row=2,
sticky='w')
ttk.Separator(self, orient='horizontal').grid(column=0,
row=1, columnspan=4, sticky='ew')
for child in self.winfo_children():
child.grid_configure(padx=5, pady=5)
if __name__ == '__main__':
root = tkinter.Tk()
Adder(root)
root.mainloop()
IIUC the problem is you cannot just plug in a variable name like that. You'll have to do:
connstr = '''Driver={{SQL Server}};Server={};Database=mydatabase;Trusted_Connection=yes;'''.format(serverName)
connection = pypyodbc.connect(connstr)