|
|
|
|
from tkinter import Frame
|
|
|
|
|
import tkinter.font as tkFont
|
|
|
|
|
|
|
|
|
|
from ttkbootstrap import *
|
|
|
|
|
import ttkbootstrap as ttk
|
|
|
|
|
from ttkbootstrap.constants import *
|
|
|
|
|
|
|
|
|
|
import pandas as pd
|
|
|
|
|
import pymysql
|
|
|
|
|
from ttkbootstrap.toast import ToastNotification
|
|
|
|
|
|
|
|
|
|
from BaseWindow import BaseWindow
|
|
|
|
|
from X2.StuSys_X2_bootstrap import LoadElement
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_text_content(text):
|
|
|
|
|
return text.get("0.0", "end").replace("\n", " ")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class FormElement(Frame):
|
|
|
|
|
def __init__(self, master):
|
|
|
|
|
super().__init__(master)
|
|
|
|
|
self.master = master
|
|
|
|
|
self.data = []
|
|
|
|
|
self.conn = pymysql.connect(user="root", password="Wyz010810", database="SCT", host="127.0.0.1", port=3306)
|
|
|
|
|
self.font_style = tkFont.Font(family="Lucida Grande", size=20)
|
|
|
|
|
self.button_font = tkFont.Font(family="Lucida Grande", size=10)
|
|
|
|
|
self.default_query_sql = "select * from student"
|
|
|
|
|
self.create_form()
|
|
|
|
|
self.create_treeview(pd.read_sql(self.default_query_sql, con=self.conn))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_form(self):
|
|
|
|
|
"""
|
|
|
|
|
创建表单
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
self.sid_var = IntVar()# 学号
|
|
|
|
|
self.sname_var = IntVar()# 姓名
|
|
|
|
|
self.sclass_var = IntVar()# 班级
|
|
|
|
|
self.ssex_var = IntVar()# 性别
|
|
|
|
|
self.sage_var = IntVar()# 年龄
|
|
|
|
|
Label(self, text="学号", font=self.font_style).grid(row=0, column=0, sticky=W)
|
|
|
|
|
# 创建复选框,表示选择条件的选择状态,并将变量进行关联
|
|
|
|
|
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sid_var).grid(row=0, column=1, sticky=W)
|
|
|
|
|
self.sid = Entry(self, width=20, font=self.font_style) # 条件输入文本框
|
|
|
|
|
self.sid.grid(row=0, column=2, sticky=W)
|
|
|
|
|
|
|
|
|
|
# ... 其他字段部分的创建类似,以下省略
|
|
|
|
|
Label(self, text="姓名", font=self.font_style).grid(row=0, column=3, sticky=W)
|
|
|
|
|
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sname_var).grid(row=0, column=4, sticky=W)
|
|
|
|
|
self.sname = Entry(self, width=20, font=self.font_style) # 选择条件文本框
|
|
|
|
|
self.sname.grid(row=0, column=5, sticky=W)
|
|
|
|
|
|
|
|
|
|
Label(self, text="班级", font=self.font_style).grid(row=1, column=0, sticky=W)
|
|
|
|
|
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sclass_var).grid(row=1, column=1, sticky=W)
|
|
|
|
|
self.sclass = Entry(self, width=20, font=self.font_style)
|
|
|
|
|
self.sclass.grid(row=1, column=2, sticky=W)
|
|
|
|
|
Label(self, text="性别", font=self.font_style).grid(row=1, column=3, sticky=W)
|
|
|
|
|
Checkbutton(self, onvalue=1, offvalue=0, variable=self.ssex_var).grid(row=1, column=4, sticky=W)
|
|
|
|
|
self.ssex = Entry(self, width=20, font=self.font_style)
|
|
|
|
|
self.ssex.grid(row=1, column=5, sticky=W, pady=10)
|
|
|
|
|
Label(self, text="年龄自", font=self.font_style).grid(row=2, column=0, sticky=W)
|
|
|
|
|
|
|
|
|
|
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sage_var).grid(row=2, column=1, sticky=W)
|
|
|
|
|
self.start_age = Entry(self, width=20, font=self.font_style)
|
|
|
|
|
self.start_age.grid(row=2, column=2, sticky=W)
|
|
|
|
|
Label(self, text="到", font=self.font_style).grid(row=2, column=3, sticky=W)
|
|
|
|
|
Label(self, text="", font=self.font_style).grid(row=2, column=4, sticky=W)
|
|
|
|
|
self.end_age = Entry(self, width=20, font=self.font_style)
|
|
|
|
|
self.end_age.grid(row=2, column=5, sticky=W, pady=10)
|
|
|
|
|
|
|
|
|
|
Button(self, text="\n\n构造SQL\n\n", command=self.make_sql, width=8,
|
|
|
|
|
).grid(column=8, row=0, rowspan=3)
|
|
|
|
|
|
|
|
|
|
self.sql_text = Text(self, height=3, font=self.font_style, width=75)
|
|
|
|
|
self.sql_text.grid(row=4, column=0, rowspan=2, columnspan=7, sticky=W)
|
|
|
|
|
Button(self, text="\n执行SQL\n", command=self.execute_sql, width=8,
|
|
|
|
|
).grid(column=8, row=4, rowspan=2, padx=10)
|
|
|
|
|
self.sql_text.insert(1.0, self.default_query_sql)
|
|
|
|
|
|
|
|
|
|
def execute_sql(self):
|
|
|
|
|
sql = get_text_content(self.sql_text).lower().strip()
|
|
|
|
|
if sql.startswith("select"):
|
|
|
|
|
data_frame = pd.read_sql(sql, con=self.conn)
|
|
|
|
|
self.create_treeview(data_frame)
|
|
|
|
|
ToastNotification(message="语句执行成功",
|
|
|
|
|
title="提示",
|
|
|
|
|
duration=1500,
|
|
|
|
|
position=(int(self.winfo_screenwidth() / 2) - 150, 80, "ne"),
|
|
|
|
|
bootstyle="success",
|
|
|
|
|
icon="").show_toast()
|
|
|
|
|
#""
|
|
|
|
|
def create_treeview(self, data_frame):
|
|
|
|
|
frame = Frame(self, height=600)
|
|
|
|
|
frame.grid(row=10, column=0, columnspan=10, rowspan=5, sticky=NSEW)
|
|
|
|
|
frame.grid_columnconfigure(0, weight=1)
|
|
|
|
|
frame.grid_rowconfigure(0, weight=1)
|
|
|
|
|
columns = data_frame.keys().tolist()
|
|
|
|
|
tree = ttk.Treeview(frame, columns=columns, show="headings", style="mystyle.Treeview", height=50,
|
|
|
|
|
selectmode=BROWSE)
|
|
|
|
|
style = ttk.Style()
|
|
|
|
|
style.configure("Treeview.Heading", font=self.font_style)
|
|
|
|
|
style.configure("Treeview", rowheight=30, font=self.font_style, borderwidth=1)
|
|
|
|
|
# 根据dataFrame结构生成表
|
|
|
|
|
for i in columns:
|
|
|
|
|
tree.heading(column=i, text=i)
|
|
|
|
|
for i in columns:
|
|
|
|
|
tree.column(i, anchor=CENTER, minwidth=100, width=100)
|
|
|
|
|
for row in data_frame.itertuples():
|
|
|
|
|
tree.insert(parent="", index=END, values=[row[i] for i in range(1, len(row))])
|
|
|
|
|
tree.grid(row=0, column=0, sticky=NSEW, pady=10)
|
|
|
|
|
y_scrollbar = ttk.Scrollbar(frame, orient='vertical', command=tree.yview)
|
|
|
|
|
tree.configure(yscrollcommand=y_scrollbar.set)
|
|
|
|
|
y_scrollbar.grid(row=0, column=1, sticky='ns')
|
|
|
|
|
frame.grid_propagate(False)
|
|
|
|
|
|
|
|
|
|
def make_sql(self):
|
|
|
|
|
"""
|
|
|
|
|
获取用户输入,进行条件判断,进行SQLString的构造
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
# 根据表单条件生成sql语句
|
|
|
|
|
SQLString = "select * from student where 1=1"
|
|
|
|
|
if self.sid.get() != "":
|
|
|
|
|
SQLString += f" and (sid like '{self.sid.get()}')"
|
|
|
|
|
if self.sname.get() != "":
|
|
|
|
|
SQLString += f" and (sname like '{self.sname.get()}')"
|
|
|
|
|
if self.sclass.get() != "":
|
|
|
|
|
SQLString += f" and (sclass like '{self.sclass.get()}')"
|
|
|
|
|
if self.ssex.get() != "":
|
|
|
|
|
SQLString += f" and (ssex like '{self.ssex.get()}')"
|
|
|
|
|
if self.start_age.get() != "":
|
|
|
|
|
SQLString += f" and (sage > '{self.start_age.get()}')"
|
|
|
|
|
if self.end_age.get() != "":
|
|
|
|
|
SQLString += f" and (sage < '{self.end_age.get()}')"
|
|
|
|
|
if SQLString == "select * from student where 1=1":
|
|
|
|
|
SQLString = "select * from student"
|
|
|
|
|
SQLString = SQLString.replace("1=1 and", "")
|
|
|
|
|
if (self.sid_var and self.ssex_var and self.sage_var and self.sclass_var and self.sname_var == 0):
|
|
|
|
|
pass
|
|
|
|
|
else:
|
|
|
|
|
data = []
|
|
|
|
|
data.append("sid")if self.sid_var.get() == 1 else ""
|
|
|
|
|
data.append("sname")if self.sname_var.get() == 1 else ""
|
|
|
|
|
data.append("ssex")if self.ssex_var.get() == 1 else ""
|
|
|
|
|
data.append("sage")if self.sage_var.get() == 1 else ""
|
|
|
|
|
data.append("sclass")if self.sclass_var.get() == 1 else ""
|
|
|
|
|
SQLString = SQLString.replace("select *", f"select {', '.join(data)} ")
|
|
|
|
|
self.sql_text.delete(0.0, END)
|
|
|
|
|
self.sql_text.insert(1.0, SQLString)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class StuSys_X4(BaseWindow):
|
|
|
|
|
def __init__(self, master, attr):
|
|
|
|
|
super().__init__(master, attr)
|
|
|
|
|
self.create_left_plate()
|
|
|
|
|
self.create_right_plate()
|
|
|
|
|
|
|
|
|
|
def create_left_plate(self):
|
|
|
|
|
self.left_frame = Frame(self.master, height=self.attr["height"])
|
|
|
|
|
self.left_frame.pack(side=LEFT, anchor=NW, pady=10, padx=10)
|
|
|
|
|
load_element1 = LoadElement(self.left_frame, "student")
|
|
|
|
|
load_element1.pack(side=TOP, pady=10)
|
|
|
|
|
load_element2 = LoadElement(self.left_frame, "course")
|
|
|
|
|
load_element2.pack(side=TOP, pady=10)
|
|
|
|
|
load_element2 = LoadElement(self.left_frame, "sc")
|
|
|
|
|
load_element2.pack(side=TOP, pady=10)
|
|
|
|
|
|
|
|
|
|
def create_right_plate(self):
|
|
|
|
|
self.right_frame = Frame(self.master, height=self.attr["height"])
|
|
|
|
|
self.right_frame.pack(side=LEFT, anchor=NW, pady=10, padx=10, fill=BOTH)
|
|
|
|
|
form_element = FormElement(self.right_frame)
|
|
|
|
|
form_element.pack(side=TOP, pady=10, anchor=NE, fill=BOTH)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
"""
|
|
|
|
|
minty, lumen, sandstone, yeti, pulse, united, morph, journal, darkly, superhero, solar
|
|
|
|
|
cyborg, vapor, simplex, cerculean,
|
|
|
|
|
"""
|
|
|
|
|
style = "morph"
|
|
|
|
|
root = Window(themename=style)
|
|
|
|
|
screenwidth = root.winfo_screenwidth()
|
|
|
|
|
screenheight = root.winfo_screenheight()
|
|
|
|
|
root.columnconfigure(0, weight=1)
|
|
|
|
|
root.rowconfigure(1, weight=1)
|
|
|
|
|
root_attr = {
|
|
|
|
|
"width": screenwidth * 0.83,
|
|
|
|
|
"height": screenheight * 0.85,
|
|
|
|
|
}
|
|
|
|
|
alignstr = '%dx%d+%d+%d' % (root_attr['width'], root_attr['height'], (screenwidth - root_attr['width']) / 2,
|
|
|
|
|
(screenheight - root_attr['height']) / 2)
|
|
|
|
|
root.geometry(alignstr)
|
|
|
|
|
root.resizable(width=False, height=False)
|
|
|
|
|
app = StuSys_X4(root, root_attr)
|
|
|
|
|
|
|
|
|
|
ttk.Style().configure("TButton", font="-size 18")
|
|
|
|
|
root.mainloop()
|