How do I make the checkboxes stay ticked? I want it to save to a local database. Here is where I gave up:
import sqlite3
import tkinter as tk
from tkinter import ttk
from tkinter import *
from tkinter.ttk import *
from sqlite3 import *
import json
box = Tk()
box.geometry('600x450')
box.title('November Assesment Study List')
box.resizable(False,False)
checkbox1 = tk.StringVar()
checkbox2 = tk.StringVar()
checkbox3 = tk.StringVar()
checkboxes = []
sql_as_text = json.dumps(checkboxes)
checkboxes.append(checkbox1)
checkboxes.append(checkbox2)
checkboxes.append(checkbox3)
connection = sqlite3.connect("Checkedboxes.db")
cursor = connection.cursor()
# cursor.execute("CREATE TABLE Valees (checked integer)")
# query = "INSERT INTO Valees (checked) VALUES (?)"
cursor.execute("INSERT INTO Valees (checked) VALUES )")
# cursor.execute(query, [sql_as_text])
r = cursor.fetchall()
def btn1_checked():
w = checkbox1.get()
checkboxes.append(w)
print(str(checkboxes))
print(r)
def openNewWindow1():
newWindow = Toplevel(box)
newWindow.title("Maths")
newWindow.geometry("400x200")
ttk.Checkbutton(newWindow, text= 'Algebra', command=btn1_checked, variable=checkbox1, onvalue='1', offvalue='0').pack()
ttk.Checkbutton(newWindow, text= 'Calculus', onvalue='1', offvalue='0').pack()
ttk.Checkbutton(newWindow, text= 'Trig', onvalue='1', offvalue='0').pack()
btn = Button(box,
text ="Maths",
command = openNewWindow1)
btn.pack(pady = 10)
cursor.close()
connection.commit()
connection.close()
box.mainloop()
You could also use a local file. Would be a different approach, but then there is no need to install mysql first.
But you were right. You need to store the state of the checkbox somewhere.
checkbox1 = True
f = open("file.txt", "a") # "a" will append to the end of the file.
f.write("checkbox1=" + str(checkbox1) + "\n") # "\n" will create a new paragraph
f.close()
# open read the file
f = open("file.txt", "r")
print(f.read())
Something like this ;)
Related
I have a dropdown menu that gets it's options from a sqlite database. I have a function that adds to the dropdown, but I'm struggling to make a delete function. I want the option menu selection to get deleted if you press delete. Could someone please help me with this? Thanks.
from tkinter import *
import os
import sqlite3
# init window
window=Tk()
window.title("Scheduling Assistant")
window.geometry("400x300")
addname1 = Label(text="Add Last Name:")
addname = Entry()
addquality1 = Label(text="Add Quality (A,B, or C):")
addquality = Entry()
addname1.pack()
addname.pack()
addquality1.pack()
addquality.pack()
# create table
conn = sqlite3.connect("dentist0.db")
c = conn.cursor()
c.execute("""CREATE TABLE IF NOT EXISTS densist(
last_name text,
class text)""")
clicked = StringVar()
drpdwn = OptionMenu(window, clicked, [])
def update_menu():
c.execute("SELECT last_name FROM densist")
all = c.fetchall()
print(all)
drpdwn['menu'].delete(0, 'end')
for choice in all:
drpdwn['menu'].add_command(label=choice)
def click1():
lstnme = addname.get()
quality = addquality.get()
sql = "INSERT INTO densist VALUES (?,?)"
c.execute(sql, [lstnme, quality])
conn.commit()
update_menu()
def click2():
sql2="DELETE FROM densist WHERE last_name=last_name"
c.execute(sql2)
conn.commit()
submit = Button(text='Add',command=click1)
submit2=Button(text='Delete', command=click2)
submit.pack()
submit2.pack()
drpdwn.pack()
update_menu()
window.mainloop()
I am currently using Psycopg2 to run 4 separate SQL queries from 4 different tables. The data itself needs to be separated for what I intend to use it for, which is why I am doing it this way. Of the 4 SQL tables that I am pulling from, 3 are under 2mil rows, while the 4th is significantly larger at nearly 24mil rows. It is a very simple statement, basically:
SELECT row1, row2, row3, row4 FROM largetable WHERE row1 = {value};
Which returns usually 10-20 matching rows.
I am designing an app for my coworkers to look up this data and display it via a Tkinter window (which I will leave out of the MCVE). Given what they need to do with it, I need it to populate as fast as possible. The entire load up and populate runs about 10 seconds, with about 5-6 seconds being spent solely on this one SQL. The script grants read-only access to the database, so manipulation of the table is not possible.
Here is an MCVE of the part I need to speed up in my py script. The SQL files all follow the simple outline above but pull from different tables. We can say query_d is the largest.
import psycopg2
from config import config
import tkinter as tk
from tkinter import *
from tkinter.ttk import *
import tkinter.messagebox
def get_val():
class GetValue(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.label = tk.Label(text="Input Control")
self.label.config(font=("Ariel", 24))
self.entry = tk.Entry(self)
self.entry.config(font=("Ariel",18),justify='center')
self.button = tk.Button(self, text="Populate",
command=self.on_button)
self.label.pack()
self.entry.pack()
self.button.pack(pady=5)
self.bind("<Return>",self.on_button)
self.bind("<KP_Enter>",self.on_button)
self.entry.focus_force()
def on_button(self, event=None):
global val
try:
val = int(self.entry.get())
except:
tk.messagebox.showerror("Invalid Entry", "Entry must be a
number.")
else:
if control:
conn = None
try:
params = config()
conn = psycopg2.connect(**params)
cur = conn.cursor()
global value
value = {'value':value}
query_a = open("query_a.sql", "r")
a = query_a.read()
a = a.format(**value)
cur.execute(a)
global response_a
response_a = cur.fetchall()
query_a.close()
query_b = open("query_b.sql", "r")
b = query_b.read()
b = b.format(**value)
cur.execute(b)
global response_b
response_b = cur.fetchall()
query_b.close()
query_c = open("query_c.sql", "r")
c = query_c.read()
c = c.format(**value)
cur.execute(c)
global response_c
response_c = cur.fetchall()
query_c.close()
query_d = open("query_d.sql", "r")
d = query_d.read()
d = d.format(**value)
cur.execute(d)
global response_d
response_d = cur.fetchall()
query_d.close()
finally:
if conn is not None:
conn.close()
app = GetValue()
app.mainloop()
if __name__ == '__main__':
get_control()
With these factors in mind, is it possible to speed up this query?
Per #jordanm and #Belayer I have added an index to each table and increased the speed from about 7-8 seconds to about 0.12 seconds.
Empty entries filled in MySQL tables (Python + Tkinter)
Having a problem of data entry in MySQL. At the time of entry it don't take any value from me or
user. And one more thing I want to add multiple pages. But how can I make button to submit the value and direct to page 2. please if anyone know then please me.
Thank you
Here he the table which is completely empty.
from tkinter import *
import mysql.connector
from PIL import Image,ImageTk
m=Tk()
button_bg='#FF9200'
button_fg='#fff'
active_button_fg='#FF9200'
active_button_bg='#fff'
def tkinter_setup():
m.geometry('1024x720')
def database_connectivity():
FullName=StringVar()
CollegeName=StringVar()
Email = StringVar()
Password=IntVar()
CGPA= IntVar()
fullName=FullName.get()
collegeName=CollegeName.get()
email=Email.get()
password=Password.get()
cgpa=CGPA.get()
mydb = mysql.connector.connect(host="localhost", user="root", passwd="ashu12",database='mySchool')
cursor=mydb.cursor()
cursor.execute('CREATE TABLE IF NOT EXISTS Student (FullName TEXT,CollegeName TEXT,Email TEXT,Password INT,CGPA INT)')
cursor.execute('INSERT INTO Student (FullName,CollegeName,Email,Password,CGPA) VALUES(%s,%s,%s,%s,%s)',(fullName,collegeName,email,password,cgpa))
mydb.commit()
def page2():
entry7 = Entry(m,width=70)
entry7.place(x=0,y=30)
entry7.insert(0,'Full Name')
m.mainloop()
def page1():
Image_open=Image.open("1.png")
image=ImageTk.PhotoImage(Image_open)
logo=Label(m,image=image)
logo.place(x=0,y=0,bordermode="outside")
entry1 = Entry(m,textvar='FullName',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=154)
entry1 = Entry(m,width=42,textvar='Collegename',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=210)
entry1 = Entry(m,width=42,textvar='Email',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=266)
entry1 = Entry(m,width=42,textvar='Password',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=322)
entry1 = Entry(m,width=42,textvar='CGPA',font="Ubuntu")
entry1.place(height=45,width=397,x=145,y=377)
button = Button(m,text='Registration' , bg=button_bg,foreground=button_fg,activebackground=active_button_bg,activeforeground=active_button_fg,command=page2 )
button.place(height=47, width=399 ,x=144,y=476)
m.mainloop()
tkinter_setup()
database_connectivity()
page1()
page2()
I want to use Tkinter to create a search form where the user can input the name they want to see from the SQLite3 database. A database named New_Assignment has all the details about the person. But I am confused about how to connect the Tkinter to the database and use the name to search? This is what I have got so far.
import sqlite3
conn = sqlite3.connect('new_assignment.db')
c = conn.cursor()
from tkinter import *
top = Tk()
top.title('Search form')
person_name = Entry()
person_name.pack(side = RIGHT, expand = True)
mainloop()
To get the text from the Entry widget, use the get() method (it returns the string in the textbox).
name_box = Entry()
name_box.pack(side=RIGHT, expand=True)
person_name = name_box.get()
However, you will need to add a button as #abarnert says in the comments. Attach this function to it:
def get_name():
global person_name
person_name = name_box.get()
data = c.fetchall()
print(data)
for row in data:
searchlist.append(row)
var1=str(person_name)
read_from_db(var1)
(Of couse, modify read_from_db() to take a variable like so:
def read_from_db(var):
curs.execute("SELECT *" + " FROM personal WHERE Name LIKE (?)", ('%'+var+'%',))
)
An example of the code for a button might look like this:
button = Button(top, text="Display text", command=get_name)
Place it all together:
import sqlite3
conn = sqlite3.connect('new_assignment.db')
c = conn.cursor()
from tkinter import *
top = Tk()
top.title('Search form')
name_box = Entry()
name_box.pack(side = RIGHT, expand = True)
def get_name():
global person_name
person_name = name_box.get()
data = c.fetchall()
print(data)
for row in data:
searchlist.append(row)
var1=str(person_name)
read_from_db(var1)
def read_from_db(var):
curs.execute("SELECT *" + " FROM personal WHERE Name LIKE (?)", ('%'+var+'%',))
person_name = ""
button = Button(top, text="Display text", command=get_name)
button.pack()
mainloop()
from tkinter import *
import tkinter as tk
import pyodbc
root1 = tk.Tk()
label1 = tk.Label(root1, text='product A')
input1 = StringVar()
entry1 = tk.Entry(root1,textvariable=input1)
label1.pack(side = tk.TOP)
entry1.pack()
buttonstr = tk.StringVar()
db = r"C:\Users\Goutham\Documents\keshav\testdb.accdb"
def odbc():
'''
connects with odbc
'''
constr = 'Driver={Microsoft Access Driver (*.mdb, *.accdb)};Dbq=' + db
conn = pyodbc.connect(constr, autocommit=True)
cur = conn.cursor()
check=input1.get()
strsql = "select * from student where SName=%s"%(check)
cur.execute(strsql)
results = cur.fetchall()
print (results,check)
conn.close()
buttonA = tk.Button(text = "hello", command = odbc)
buttonA.pack()
I need this code to get input,store it in the variable -'check' and compare it with the values in the database using a SQL query.The matching values from the database are then displayed.
There seems to be a problem in the implementation of the SQL query.'check' stores the value of the input. The SQL query does not work properly and causes errors.
Please help.
Thank you.
You need to single quote the parameter to the WHERE clause:
strsql = "select * from student where SName='%s'" % (check,)
But be careful with building clauses like this (using string formatting), you run the risk of SQL injection. You should pass parameters instead:
strsql = "select * from student where SName=?"
cur.execute(strsql, (check,))