Basically I am trying to get my database to connect to my GUI and display a random question, however it is simply not working, any idea?
SQL = 'SELECT * FROM tblQuestion'
cursor = Databaseconnector.SELECT(SQL)
rows = cursor.fetchall()
rows = random.choice(rows)
print rows.Question, rows.Hint, rows.A1, rows.A2, rows.A3, rows.A4, rows.CorrectAnswer
#def create_widgets(self):
#create welcome label
label1 = Tkinter.Label(self, text = (rows(1).Question))
label1.grid(row = 0, column = 1, columnspan = 2, sticky = 'W')
ERROR: TypeError: ‘pydodbc.Row’ object is not
rows is first a collection of pydodbc.Row objects, but then you alter it to be a single pydodbc.Row object by calling random.choice:
rows = cursor.fetchall() # rows is a list
rows = random.choice(rows) # now rows is a single object
Then you try to call that object using ():
label1 = Tkinter.Label(self, text = (rows(1).Question))
which fails with the error message you provided (partially):
ERROR: TypeError: ‘pydodbc.Row’ object is not callable
The best way to solve this to use a new variable for the single row:
rows = cursor.fetchall()
random_row = random.choice(rows)
...
label1 = Tkinter.Label(self, text = (random_row.Question))
Related
This is my two functions which operate my search. The problem seems to occur with my search function when I binded it to my key releases on my search entries. However when I search with my button it works with no error messages .
def SearchCustomer(self):
connection = sqlite3.connect("Guestrecord.db")
cursor = connection.cursor()
columnID = ["title","firstName","surname","dob","payment","email","address","postcode"]
columnStr =["Title","FirstName","Surname","DOB","Payment","Email","Address","Postcode"]
self.search_table = ttk.Treeview(self.search_frame,columns=columnID,show="headings")
self.search_table.bind("<Motion>","break")
for i in range(0,8):
self.search_table.heading(columnID[i],text = columnStr[i])
self.search_table.column(columnID[i],minwidth = 0, width = 108)
self.search_table.place(x=20,y=0)
for GuestRec in cursor.execute("SELECT * FROM tb1Guest1"):
self.search_table.insert("",END,values=GuestRec)
connection.commit()
connection.close()
SearchCustomer(self)
search_icon = Image.open("search icon.png")
search_icon_resize = search_icon.resize((20,20))
search_icon = search_icon_resize
search_icon_photo = ImageTk.PhotoImage(search_icon)
self.search_firstname = Entry(self.search_frame2, width=30,bg="#e2f0d9",font=("Avenir Next",18),highlightthickness = 0,relief=FLAT)
self.search_firstname.place(x = 140, y =0)
self.search_firstname_label = Label(self.search_frame2,bg = "white", text = "First Name", font=("Avenir Next",20))
self.search_firstname_label.place(x= 20,y=0)
self.search_Surname = Entry(self.search_frame2, width=30,bg="#e2f0d9",font=("Avenir Next",18),highlightthickness = 0,relief=FLAT)
self.search_Surname.place(x = 140, y =40)
self.search_Surname_label = Label(self.search_frame2,bg = "white", text = "Surname", font=("Avenir Next",20))
self.search_Surname_label.place(x= 20,y=40)
searchButton = Button(self.search_frame2, image=search_icon_photo,height = 35, width =35, command=self.Search,bg ="white")
searchButton.place(x= 500, y = 0)
## Binding entries
self.search_firstname.bind("<KeyRelease>",self.Search)
self.search_Surname.bind("<KeyRelease>",self.Search)
def Search(self):
sFirst_Name = self.search_firstname.get()
sSurname = self.search_Surname.get()
search_rec = (sFirst_Name,sSurname)
search_rec_new = tuple(item for item in search_rec if item !="")
search_fields = ["guestFirstname","guestFirstname"]
search_SQL = "SELECT * FROM tb1Guest1 WHERE guestID LIKE '%'"
for i in range(len(search_rec)):
if search_rec[i] != "":
search_SQL += " AND " + search_fields[i] + " LIKE '%' || ? || '%'"
connection = sqlite3.connect("Guestrecord.db")
cursor = connection.cursor()
# Clearing search results
for rec in self.search_table.get_children():
self.search_table.delete(rec)
#Display the records
for GuestRec in cursor.execute(search_SQL,search_rec_new):
self.search_table.insert("",END,values=GuestRec)
connection.commit()
connection.close()
Then this is the message which pops up when I try to type in my search entries:
It may have something to do with my .self but I don't know how I would over come this error
Exception in Tkinter callback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/tkinter/__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
TypeError: Main_menu.Search() takes 1 positional argument but 2 were given
If someone could provide a solution to my problem it would be great as I have spend seemingly a lot of time trying to figure this error out.
The function for a binding event expects an argument: the Event object. However you also use the same function for a button command which does not expect that extra argument.
So you need to add an optional argument to Search():
# event argument is optional, if not provided, it will be None
def Search(self, event=None):
...
I'm trying to make a products' management app with tkinter and sqlite 3.
I want to show the products in labels. It works correctly, but I also want to delete every label when I add an item, and then recreate new labels. This way, the list updates when adding a new item.
Otherwise the user needs to restart the app to see the new item. Here's the code:
from tkinter import *
import sqlite3
# table name = items
conn = sqlite3.connect("productManagement.db")
cursor = conn.cursor()
itemsSearch = cursor.execute("SELECT rowid, * FROM items")
itemsFetch = itemsSearch.fetchall()
window = Tk()
window.geometry("800x600")
window.config(bg="#9BB7D4")
#FUNCTIONS
itemFrame = Frame(bg="#8a8a8a",width=200,height=200)
frameTitle = Label(itemFrame,text="Products:",bg="#8a8a8a",font=("Arial Black",12))
frameTitle.pack()
def createProduct():
global itemsFetch
name = nameEntry.get()
price = priceEntry.get()
quantity = quantityEntry.get()
number = numberEntry.get()
cursor.execute(f"INSERT INTO items VALUES ('{name}',{int(price)},{int(quantity)},
{int(number)})")
conn.commit()
itemsSearch = cursor.execute("SELECT rowid, * FROM items")
itemsFetch = itemsSearch.fetchall()
#the problem is here: i create new label for every item but the old ones doesn't
dissapear, i want to delete all the labels of the items existing and create new ones
showProducts()
def showProducts():
global itemStats
for item in itemsFetch:
itemStats = Label(itemFrame,bg="#8a8a8a",font=("Italic",12),
text=f"Name: {item[1]} Price: {int(item[2])}€ Quantity: {int(item[3])}
Item no: {int(item[4])}")
deleteBtn = Button(itemFrame,text="Delete")
itemStats.pack()
showProducts()
#GUI
title = Label(text="Product Managment System",font=("Arial Black",24),bg="#9BB7D4")
nameText = Label(text="Name:",bg="#9BB7D4",font=("Italic",12))
nameEntry = Entry(font=("Italic",12))
priceText = Label(text="Price:",bg="#9BB7D4",font=("Italic",12))
priceEntry = Entry(font=("Italic",12))
quantityText = Label(text="Quantity:",bg="#9BB7D4",font=("Italic",12))
quantityEntry = Entry(font=("Italic",12))
numberText = Label(text="Product Number:",bg="#9BB7D4",font=("Italic",12))
numberEntry = Entry(font=("Italic",12))
createProductBtn = Button(text="Create item",command=createProduct)
#PACKS
title.pack(pady=20)
nameText.place(x=140,y=140)
nameEntry.place(x=190,y=140)
priceText.place(x=340,y=140)
priceEntry.place(x=387,y=140)
quantityText.place(x=125,y=200)
quantityEntry.place(x=190,y=200)
numberText.place(x=340,y=200)
numberEntry.place(x=463,y=200)
createProductBtn.place(x=190,y=260)
itemFrame.place(x=190,y=300)
conn.commit()
window.mainloop()
conn.close()
I'm trying to put data from a database (SQLite3) into a set of entry fields in Tkinter.
My hope is that the data-snippets that exist in the database query will be put into the entries to show the user what info is in the db and give the choice to update empty fields.
I however have a hard time dealing with the returned None fields from the DB. None cannot be inserted into entries using .insert()
I've tried to sanitize the data first but since the different data are ints and text's I have not find a suitable replacement. I would also prefer the entries to be empty unless there is actual data to place there.
I've also tried to do an if statement before each line in the vendors_to_fields function but that did not work and seemed really messy.
Bonus question:
Is there a better way to insert values from a tuple into the different entries? I've been thinking about making 2 lists and using list comprehension but I could not solve it.
I hope I make sense, this has been a long coding session
Thank you for all input
My code:
def Order_window():
ord_win = Toplevel(root)
ord_win.title('Orders')
ord_win.geometry('800x600')
i = 0
# Functions
def controller():
vendor_list = list(vendors)
if i <= len(vendor_list):
vendor = vendor_list[i]
print(vendor)
data_from_db(vendor)
else:
vendor_name['text'] = 'All orders are done'
def data_from_db(vendor):
vendor_info_tuple = db.execute(
'SELECT * FROM vendors WHERE (vendor_id = ?)', [vendor])
vendor_info_tuple = vendor_info_tuple.fetchone()
connection.commit()
vendor_info = list(vendor_info_tuple)
if vendor_info[0] is None:
vendor_name['text'] == 'Vendor not in DB, better call Sal'
else:
print(vendor_info)
vendor_to_fields(vendor_info)
def vendor_to_fields(vendor_info):
for field in vendor_info:
if field is None:
vendor_info[field] = 0
print(vendor_info)
vendor_name['text'] = vendor_info[1]
vendor_min1.insert(0, vendor_info[5])
vendor_email.insert(0, vendor_info[2])
vendor_cc.insert(0, vendor_info[3])
vendor_message.insert(0, vendor_info[4])
def next_vendor():
pass
def update_db():
pass
# Layout order window
Label(ord_win, text='Vendor').grid(row=0)
Label(ord_win, text='Min order value').grid(row=1)
Label(ord_win, text='Email').grid(row=2)
Label(ord_win, text='CC').grid(row=3)
Label(ord_win, text='Message').grid(row=4)
vendor_name = Label(ord_win).grid(row=0, column=1)
vendor_min1 = Entry(ord_win)
vendor_min1.grid(row=1, column=1)
vendor_email = Entry(ord_win)
vendor_email.grid(row=2, column=1)
vendor_cc = Entry(ord_win)
vendor_cc.grid(row=3, column=1)
vendor_message = Entry(ord_win)
vendor_message.grid(row=4, column=1)
controller()
i keep getting this error when i try to add a column and give it a name
sqlite3.OperationalError: near "100": syntax error
here is my code (minimal)
from tkinter import *
import sqlite3
from tkinter import messagebox
conr = sqlite3.connect("CE.db")
curr = conr.cursor()
rt = Tk()
def add():
ID = e30.get()
curr.execute('alter table cust add {}'.format(ID))
lbl30 = Label(rt, text= "Your ID")
lbl30.grid (row = 0, column = 0)
e30 = Entry(rt, width = 30)
e30.grid(row = 0, column = 1)
buttt1 = Button(rt, text = 'Submit', command = add, width = 20)
buttt1.grid(row = 1, column = 0, columnspan = 2)
rt.mainloop()
can someone please tell me what i am doing wrong and how i can fix it.
The line
curr.execute('alter table cust add {}'.format(ID))
is being formatted and executed as
alter table cust add 100
This is not valid SQLite syntax
The correct syntax can be found at:
SQlite Alter Syntax
I am trying to send selected values from radiobuttons into a .docx file
importing what I need, focus is on docx
import tkinter as tk
from docx import Document
main = tk.Tk()
these are my options that I need to place into a word document on the left of the table, they act as questions in a survey.
info = ["option 1", "option 2", "option 3", "option 4"
]
Here I am placing radiobuttons called Yes, No & N/A which are answers to the options on the left(list of info above) and also Label to represent options or in other words questions..
vars = []
for idx,i in enumerate(info):
var = tk.IntVar(value=0)
vars.append(var)
lblOption = tk.Label(main,text=i)
btnYes = tk.Radiobutton(main, text="Yes", variable=var, value=2)
btnNo = tk.Radiobutton(main, text="No", variable=var, value=1)
btnNa = tk.Radiobutton(main, text="N/A", variable=var,value=0)
lblOption.grid(column=0,row=idx)
btnYes.grid(column=1,row=idx)
btnNo.grid(column=2,row=idx)
btnNa.grid(column=3,row=idx)
Here is my function, creating a document and saving is the easy part. My issue is that I am muddled up creating a table that will have; Options on the left (from info) at the top are the headers (see RadioButtons yes, no, & N/a). And selected data, as an example, if for option 1 I have selected No, then save the data into a .docx file with the one been selected (See example bottom of page at Desired output).
def send():
document = Document()
section = document.sections[0]
#add table
table = document.add_table(1, 4)
#style table
table.style = 'Table Grid'
#table data retrived from Radiobuttons
items = vars.get()
#populate header row
heading_cells = table.rows[0].cells
heading_cells[0].text = "Options"
heading_cells[1].text = btnYes.cget("text")
heading_cells[2].text = btnNo.cget("text")
heading_cells[3].text = btnNa.cget("text")
for item in items:
cells = table.add_row().cells
cells[0].text = #Options
cells[1].text = #Yes values
cells[2].text = #No values
cells[3].text = #N/A values
#save doc
document.save("test.docx")
#button to send data to docx file
btn = tk.Button(main, text="Send to File", command= send)
btn.grid()
main.mainloop()
this is what it opens up:
Here is the desired output:
Number 1 represents selected items from the tkinter application. But will figure out how to change it to a tick box.
I am kinda confused where I am at, I am new using docx.. been trying to read the documentation.. and this is where I digged my self a hole into.
In your current code, vars is a list of IntVars. You want to get each value individually instead of vars.get(). Also when writing to docx file, you need both info and values of radiobuttons, to track them both you can use an index.
With minimal changes to your code, you can use something like this.
def send():
...
...
heading_cells[3].text = btnNa.cget("text")
for idx, item in enumerate(vars):
cells = table.add_row().cells
cells[0].text = info[idx] # gets the option name
val = item.get() #radiobutton value
if val == 2: # checks if yes
cells[1].text = "1"
elif val == 1: # checks if no
cells[2].text = "1"
elif val == 0: # checks if N/A
cells[3].text = "1"
#save doc
document.save("test.docx")
or you can use a dictionary to map radiobuttons to cells.
valuesCells = {0: 3, 1: 2, 2: 1} # value of radiobutton: cell to write
# hard to read what's going on though
for idx, item in enumerate(vars):
cells = table.add_row().cells
cells[0].text = info[idx] # gets the option name
val = item.get()
cells[valuesCells[val]].text = "1"
#save doc
document.save("test.docx")