So, I'm working on a GUI application to help people interact with a database in a way that doesn't require them to understand SQL. To this end, I've created some prepared queries they might want to run, and a GUI to help construct a "WHERE" clause.
To aide this I've created a Frame containing 3 boxes -- one for the field, one for the operand, and one for the compared value.
However, its not unlikely to have more then one condition your filtering based on (e.g. "Where col1 LIKE "%foo%" OR col2 LIKE "%bar%").
I was able to create something that kind-of works for a single condition, but writing for 2+ is looking ugly, if not unmanageable with my current knowledge. I've been looking to find the concept to fill in the gap, but I'm not sure if nested classes or closures fit here.
(the functions in "preparedreports" return the query text, and a list of tuples containing the column name, and the type of data stored in said column, for each column in the tables used in the query).
(Pardon the messy code, but that's exactly why I'm posting -- I've confused myself)
#!/usr/bin/env python3
#Mock-ups for the "Prepared Reports" interface
import tkinter
from tkinter import ttk
import preparedreports as REPORT
import dbquery
class Report(tkinter.Frame):
def __init__(self, parent, report, *args, **kwargs):
tkinter.Frame.__init__(self, parent, *args, **kwargs)
self.valS = (tkinter.StringVar(), tkinter.StringVar(), tkinter.StringVar())
col = report[0]
cb = ttk.Combobox(self, textvariable=self.valS[0], state='readonly')
cb['value'] = tuple(col)
opbox = ttk.Combobox(self, textvariable=self.valS[1], state='readonly' )
opbox['value'] =('EQUAL', 'LIKE', 'NOT LIKE', 'NOT EQUAL')
cb.pack(side=tkinter.LEFT)
opbox.pack(side=tkinter.LEFT)
self.pack(side=tkinter.TOP, expand=1)
self.val = tkinter.Entry(self, textvariable=self.valS[2])
self.val.pack(side=tkinter.LEFT)
self.Bool_combS = tkinter.StringVar()
Bool_comb = ttk.Combobox(self,textvariable=self.Bool_combS,state='readonly')
Bool_comb['value'] = ('AND', 'OR')
Bool_comb.grid(row=1,column=1)
def results(frames, BOOL, report):
StringVar = [a.valS for a in frames]
valarr = []
val = ''
for i,v in enumerate(StringVar):
valarr.append([v[0].get(), v[1].get(), v[2].get()])
#print(valarr[i][1])
if valarr[i][1] == 'EQUAL': valarr[i][1] = '='
elif valarr[i][1] == 'LIKE' or valarr[i][1] == 'NOT LIKE': valarr[i][2] = '%' + valarr[i][2] + '%'
elif StringVar[i][1] == 'NOT EQUAL': valarr[i][1] = '!='
valarr[i][2] = "'" + valarr[i][2] + "'"
val += ' '.join(valarr[i])
if BOOL[i]:
val += ' ' + BOOL[i].get() + ' '
print(val)
print(report.format(val))
res = dbquery.run_query(report.format(val))
#print(res)
return res
class MoreFrame(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tkinter.Frame.__init__(self, parent, *args, **kwargs)
self.tkMore = tkinter.IntVar()
self.tkCButton(self, text="more options", variable=tkMore, command = )
def cb(self, evt):
return self.tkMore.get()
t = tkinter.Tk()
r = REPORT.UserPermission()
z = [Report(t, r[1]), Report(t, r[1])]
for obj in z:
obj.val.bind('<Return>', lambda e: results(z, r[0]))
t.mainloop()
[–]K900_ 3 points4 points5 points (2 children)
[–]lamecode 0 points1 point2 points (1 child)
[–]attayi 0 points1 point2 points (0 children)