parent
322a036fc5
commit
f0a03788f1
Binary file not shown.
@ -0,0 +1,17 @@
|
||||
import tkinter.font as tkFont
|
||||
import tkinter
|
||||
from tkinter import *
|
||||
from tkinter import ttk, messagebox
|
||||
|
||||
import pymysql
|
||||
|
||||
|
||||
class BaseWindow(Frame):
|
||||
def __init__(self, master, attr):
|
||||
super().__init__(master)
|
||||
self.attr = attr
|
||||
self.master = master
|
||||
self.font_style = tkFont.Font(family="Lucida Grande", size=20)
|
||||
self.button_font = tkFont.Font(family="Lucida Grande", size=10)
|
||||
self.conn = pymysql.connect(user="root", password="cyh0110", database="SCT", host="127.0.0.1", port=3306)
|
||||
|
@ -0,0 +1,52 @@
|
||||
import pymysql
|
||||
|
||||
# 创建mysql连接
|
||||
conn = pymysql.connect(user="root", password="cyh0110", host="127.0.0.1", port=3306)
|
||||
def create_database():
|
||||
cursor = conn.cursor() # 创建游标
|
||||
cursor.execute("DROP DATABASE IF EXISTS SCT")
|
||||
# 创建数据库
|
||||
cursor.execute("CREATE DATABASE SCT CHARACTER SET utf8 COLLATE utf8_general_ci")
|
||||
cursor.close() # 关闭游标
|
||||
|
||||
def create_table():
|
||||
cursor = conn.cursor() # 创建游标
|
||||
cursor.execute("USE SCT") # 指定数据库
|
||||
# 创建student数据表
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS student
|
||||
(
|
||||
sid CHAR(8) PRIMARY KEY,
|
||||
sname CHAR(10),
|
||||
ssex CHAR(2),
|
||||
sage INTEGER,
|
||||
sclass CHAR(6)
|
||||
)
|
||||
""")
|
||||
# 创建Course数据表
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS course
|
||||
(
|
||||
cid CHAR(4) PRIMARY KEY,
|
||||
cname CHAR(30),
|
||||
credit FLOAT(1),
|
||||
chours INTEGER,
|
||||
t CHAR(3)
|
||||
)
|
||||
""")
|
||||
# 创建SC数据表
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS sc
|
||||
(
|
||||
sid CHAR(8),
|
||||
cid CHAR(4),
|
||||
score FLOAT(1),
|
||||
CONSTRAINT sc_course_cid_fk
|
||||
FOREIGN KEY (cid) REFERENCES course (cid),
|
||||
CONSTRAINT sc_student_sid_fk
|
||||
FOREIGN KEY (sid) REFERENCES student (sid)
|
||||
)
|
||||
""")
|
||||
cursor.close()
|
||||
|
||||
conn.close() # 关闭链接
|
@ -0,0 +1,183 @@
|
||||
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.tableview import Tableview
|
||||
|
||||
from BaseWindow import BaseWindow
|
||||
|
||||
|
||||
def get_text_content(text):
|
||||
return text.get("0.0", "end").replace("\n", " ")
|
||||
|
||||
conn = pymysql.connect(user="root", password="cyh0110", database="SCT", host="127.0.0.1", port=3306)
|
||||
|
||||
class LoadElement(Frame):
|
||||
def __init__(self, master, table_name):
|
||||
super().__init__(master)
|
||||
self.master = master
|
||||
self.table_name = table_name
|
||||
self.TableList = pd.read_sql(f"select * from {self.table_name} limit 0", conn)
|
||||
self.font_style = tkFont.Font(family="Lucida Grande", size=20)
|
||||
self.button_font = tkFont.Font(family="Lucida Grande", size=10)
|
||||
self.create_widget()
|
||||
self.create_tree_widget()
|
||||
|
||||
def create_widget(self):
|
||||
# 创建装载按钮
|
||||
label = Label(self, width=10, font=self.font_style, text=self.table_name, style="inverse-secondary")
|
||||
label.grid(column=0, row=0)
|
||||
Button(self, text="装载", width=10, command=self.load).grid(column=1, row=0, padx=5, sticky=NSEW)
|
||||
|
||||
def create_tree_widget(self):
|
||||
frame = Frame(self, width=50, height=220)
|
||||
frame.grid(row=1, column=0, columnspan=2, sticky=NSEW, pady=5)
|
||||
frame.grid_columnconfigure(0, weight=1)
|
||||
frame.grid_rowconfigure(0, weight=1)
|
||||
columns = self.TableList.keys().tolist()
|
||||
style = ttk.Style()
|
||||
style.configure("Custom.Treeview.Heading", font=("宋体", 15))
|
||||
style.configure("Custom.Treeview", rowheight=30, font=("宋体", 15))
|
||||
tree = ttk.Treeview(frame, columns=columns, show="headings", style="Custom.Treeview", selectmode=BROWSE)
|
||||
# 根据dataFrame结构生成表
|
||||
for i in columns:
|
||||
tree.heading(column=i, text=i)
|
||||
for i in columns:
|
||||
tree.column(i, anchor=CENTER, width=80)
|
||||
if columns.index(i) == 1 or columns.index(i) == 0:
|
||||
tree.column(i, anchor=CENTER, width=120)
|
||||
for row in self.TableList.itertuples():
|
||||
tree.insert(parent="", index=END, values=[row[i] for i in range(1, len(row))])
|
||||
y_scrollbar = ttk.Scrollbar(self, orient='vertical', command=tree.yview)
|
||||
x_scrollbar = ttk.Scrollbar(frame, orient="horizontal", command=tree.xview)
|
||||
tree.configure(yscrollcommand=y_scrollbar.set)
|
||||
tree.config(height=6)
|
||||
tree.grid(row=0, column=0, columnspan=2, sticky=NSEW, pady=5)
|
||||
y_scrollbar.grid(row=1, column=3, sticky='ns')
|
||||
x_scrollbar.grid(row=2, column=0, columnspan=2, sticky='ew')
|
||||
frame.grid_propagate(False)
|
||||
|
||||
def load(self):
|
||||
"""
|
||||
加载数据
|
||||
:return:
|
||||
"""
|
||||
SQLString = f"select * from {self.table_name}"
|
||||
# 执行SQL语句 并返回列表数据
|
||||
self.TableList = pd.read_sql(SQLString, conn)
|
||||
# 调用X2界面函数将数据展示出来
|
||||
self.create_tree_widget()
|
||||
|
||||
|
||||
class FormElement(Frame):
|
||||
def __init__(self, master):
|
||||
super().__init__(master)
|
||||
self.master = master
|
||||
self.data = []
|
||||
self.conn = pymysql.connect(user="root", password="cyh0110", 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):
|
||||
# 创建表单区域
|
||||
self.sql_text = Text(self, width=75, height=4, font=self.font_style)
|
||||
self.sql_text.grid(row=0, column=0, rowspan=2)
|
||||
Button(self, text="\n\n执行SQL\n\n", command=self.execute_sql, width=7, style=INFO, compound=TOP).grid(column=1, row=0, rowspan=2, padx=10)
|
||||
self.sql_text.insert(1.0, self.default_query_sql)
|
||||
|
||||
def execute_sql(self):
|
||||
"""
|
||||
执行sql方法
|
||||
:return:
|
||||
"""
|
||||
# 获取text组件中用户输入的值
|
||||
sql = get_text_content(self.sql_text).lower().strip()
|
||||
print(sql)
|
||||
|
||||
def create_treeview(self, data_frame):
|
||||
"""
|
||||
创建数据列表展示组件
|
||||
:param data_frame:
|
||||
:return:
|
||||
"""
|
||||
frame = Frame(self, height=700)
|
||||
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)
|
||||
|
||||
|
||||
class StuSys_X2(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)
|
||||
form_element = FormElement(self.right_frame)
|
||||
form_element.pack(side=TOP, pady=10, anchor=NE)
|
||||
|
||||
|
||||
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_X2(root, root_attr)
|
||||
|
||||
ttk.Style().configure("TButton", font="-size 18")
|
||||
root.mainloop()
|
@ -0,0 +1,129 @@
|
||||
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="cyh0110", 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):
|
||||
# 创建表单区域
|
||||
self.sql_text = Text(self, width=75, height=6, font=self.font_style)
|
||||
self.sql_text.grid(row=0, column=0, rowspan=2)
|
||||
Button(self, text="\n\n执行SQL\n\n", command=self.execute_sql, width=8,
|
||||
).grid(column=1, row=0, rowspan=2, padx=10)
|
||||
self.sql_text.insert(1.0, self.default_query_sql)
|
||||
|
||||
def sql_query(self, SQLString):
|
||||
SQLResultList = pd.read_sql(SQLString, self.conn)
|
||||
return SQLResultList
|
||||
|
||||
def execute_sql(self):
|
||||
# 执行sql并将sql执行后查询的数据展示
|
||||
sql = get_text_content(self.sql_text).lower().strip()
|
||||
if sql.startswith("select"):
|
||||
data_frame = self.sql_query(sql)
|
||||
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=700)
|
||||
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)
|
||||
|
||||
|
||||
class StuSys_X3(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)
|
||||
form_element = FormElement(self.right_frame)
|
||||
form_element.pack(side=TOP, pady=10, anchor=NE)
|
||||
|
||||
|
||||
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_X3(root, root_attr)
|
||||
|
||||
ttk.Style().configure("TButton", font="-size 18")
|
||||
root.mainloop()
|
@ -0,0 +1,242 @@
|
||||
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="cyh0110", 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):
|
||||
self.sid_var = IntVar()
|
||||
self.sname_var = IntVar()
|
||||
self.sclass_var = IntVar()
|
||||
self.ssex_var = IntVar()
|
||||
self.sage_var = IntVar()
|
||||
self.score_var = IntVar()
|
||||
self.courseId_var = IntVar()
|
||||
self.cname_var = IntVar()
|
||||
self.credit_var = IntVar()
|
||||
self.chours_var = IntVar()
|
||||
Label(self, text="学生/student", font=("Lucida Grande", 20), style="inverse").grid(row=0, column=0, sticky=W)
|
||||
Label(self, text="学号", font=self.font_style).grid(row=1, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sid_var).grid(row=1, column=1, sticky=W)
|
||||
self.sid = Entry(self, width=20, font=self.font_style)
|
||||
self.sid.grid(row=1, column=2, sticky=W)
|
||||
Label(self, text="姓名", font=self.font_style).grid(row=1, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sname_var).grid(row=1, column=4, sticky=W)
|
||||
self.sname = Entry(self, width=20, font=self.font_style)
|
||||
self.sname.grid(row=1, column=5, sticky=W)
|
||||
|
||||
Label(self, text="班级", font=self.font_style).grid(row=2, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sclass_var).grid(row=2, column=1, sticky=W)
|
||||
self.sclass = Entry(self, width=20, font=self.font_style)
|
||||
self.sclass.grid(row=2, column=2, sticky=W)
|
||||
Label(self, text="性别", font=self.font_style).grid(row=2, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.ssex_var).grid(row=2, column=4, sticky=W)
|
||||
self.ssex = Entry(self, width=20, font=self.font_style)
|
||||
self.ssex.grid(row=2, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="年龄自", font=self.font_style).grid(row=3, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sage_var).grid(row=3, column=1, sticky=W)
|
||||
self.start_age = Entry(self, width=20, font=self.font_style)
|
||||
self.start_age.grid(row=3, column=2, sticky=W)
|
||||
Label(self, text="到", font=self.font_style).grid(row=3, column=3, sticky=E)
|
||||
Label(self, text="", font=self.font_style).grid(row=3, column=4, sticky=W)
|
||||
self.end_age = Entry(self, width=20, font=self.font_style)
|
||||
self.end_age.grid(row=3, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="课程/course", font=("Lucida Grande", 20), style="inverse").grid(row=4, column=0, sticky=W)
|
||||
Label(self, text="课号", font=self.font_style).grid(row=5, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.courseId_var).grid(row=5, column=1, sticky=W)
|
||||
self.course_id = Entry(self, width=20, font=self.font_style)
|
||||
self.course_id.grid(row=5, column=2, sticky=W)
|
||||
Label(self, text="课名", font=self.font_style).grid(row=5, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.cname_var).grid(row=5, column=4, sticky=W)
|
||||
self.course_name = Entry(self, width=20, font=self.font_style)
|
||||
self.course_name.grid(row=5, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="选课/sc", font=("Lucida Grande", 20), style="inverse").grid(row=6, column=0, sticky=W)
|
||||
Label(self, text="成绩大于", font=self.font_style).grid(row=7, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.score_var).grid(row=7, column=1, sticky=W)
|
||||
self.sc_start = Entry(self, width=20, font=self.font_style)
|
||||
self.sc_start.grid(row=7, column=2, sticky=W)
|
||||
Label(self, text="小于", font=self.font_style).grid(row=7, column=3, sticky=E)
|
||||
Label(self, text="", font=self.font_style).grid(row=7, column=4, sticky=W)
|
||||
self.sc_end = Entry(self, width=20, font=self.font_style)
|
||||
self.sc_end.grid(row=7, 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=8)
|
||||
|
||||
self.sql_text = Text(self, height=3, font=self.font_style, width=75)
|
||||
self.sql_text.grid(row=8, column=0, rowspan=2, columnspan=7, sticky=W)
|
||||
Button(self, text="\n执行SQL\n", command=self.execute_sql, width=8,
|
||||
).grid(column=8, row=8, 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=400)
|
||||
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):
|
||||
sql = "select * from student where 1=1"
|
||||
if self.course_id and self.course_name and self.sc_start and self.sc_end != "":
|
||||
sql = "select * from student s join sc on sc.sid=s.sid join course c on c.cid=sc.cid"
|
||||
if self.sid.get() != "":
|
||||
sql += f" and (s.sid like '{self.sid.get()}')"
|
||||
if self.sname.get() != "":
|
||||
sql += f" and (s.sname like '{self.sname.get()}')"
|
||||
if self.sclass.get() != "":
|
||||
sql += f" and (s.sclass like '{self.sclass.get()}')"
|
||||
if self.ssex.get() != "":
|
||||
sql += f" and (s.ssex like '{self.ssex.get()}')"
|
||||
if self.start_age.get() != "":
|
||||
sql += f" and (s.sage > '{self.start_age.get()}')"
|
||||
if self.end_age.get() != "":
|
||||
sql += f" and (s.sage < '{self.end_age.get()}')"
|
||||
if self.course_id.get() != "":
|
||||
sql += f" and (c.cid like '{self.course_id.get()}')"
|
||||
if self.course_name.get() != "":
|
||||
sql += f" and (c.cname like '{self.course_name.get()}')"
|
||||
if self.sc_start.get() != "":
|
||||
sql += f" and (sc.score > {self.sc_start.get()})"
|
||||
if self.sc_end.get() != "":
|
||||
sql += f" and (sc.score < {self.sc_end.get()})"
|
||||
else:
|
||||
if self.sid.get() != "":
|
||||
sql += f" and (sid like '{self.sid.get()}')"
|
||||
if self.sname.get() != "":
|
||||
sql += f" and (sname like '{self.sname.get()}')"
|
||||
if self.sclass.get() != "":
|
||||
sql += f" and (sclass like '{self.sclass.get()}')"
|
||||
if self.start_age.get() != "":
|
||||
sql += f" and (sage > '{self.start_age.get()}')"
|
||||
if self.end_age.get() != "":
|
||||
sql += f" and (sage < '{self.end_age.get()}')"
|
||||
if sql == "select * from student where 1=1":
|
||||
sql = "select * from student"
|
||||
if (self.sid_var and self.ssex_var and self.sage_var and self.sclass_var and self.sname_var and self.score_var and self.cname_var and self.credit_var and self.chours_var == 0):
|
||||
pass
|
||||
else:
|
||||
data = []
|
||||
data.append("s.sid")if self.sid_var.get() == 1 else ""
|
||||
data.append("s.sname")if self.sname_var.get() == 1 else ""
|
||||
data.append("s.ssex")if self.ssex_var.get() == 1 else ""
|
||||
data.append("s.sage")if self.sage_var.get() == 1 else ""
|
||||
data.append("s.sclass")if self.sclass_var.get() == 1 else ""
|
||||
data.append("sc.score")if self.score_var.get() == 1 else ""
|
||||
data.append("c.cid")if self.courseId_var.get() == 1 else ""
|
||||
data.append("c.cname")if self.cname_var.get() == 1 else ""
|
||||
data.append("c.credit")if self.credit_var.get() == 1 else ""
|
||||
data.append("c.chours")if self.chours_var.get() == 1 else ""
|
||||
sql = sql.replace("select *", f"select {', '.join(data)} ")
|
||||
sql = sql.replace("1=1 and", "")
|
||||
self.sql_text.delete(0.0, END)
|
||||
self.sql_text.insert(1.0, sql)
|
||||
|
||||
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)
|
||||
form_element = FormElement(self.right_frame)
|
||||
form_element.pack(side=TOP, pady=10, anchor=NE)
|
||||
|
||||
|
||||
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()
|
@ -0,0 +1,301 @@
|
||||
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
|
||||
|
||||
|
||||
def get_text_content(text):
|
||||
return text.get("0.0", "end").replace("\n", " ")
|
||||
|
||||
|
||||
class LoadElement(Frame):
|
||||
def __init__(self, master, table_name):
|
||||
super().__init__(master)
|
||||
self.master = master
|
||||
self.table_name = table_name
|
||||
self.data = []
|
||||
self.conn = pymysql.connect(user="root", password="cyh0110", database="SCT", host="127.0.0.1", port=3306)
|
||||
self.data_frame = pd.read_sql(f"select * from {self.table_name} limit 0", self.conn)
|
||||
self.font_style = tkFont.Font(family="Lucida Grande", size=20)
|
||||
self.button_font = tkFont.Font(family="Lucida Grande", size=10)
|
||||
self.create_widget()
|
||||
self.select_value(None)
|
||||
self.create_tree_widget()
|
||||
|
||||
def select_value(self, event):
|
||||
self.table_name = self.select_stringVar.get()
|
||||
|
||||
def create_widget(self):
|
||||
data_frame = pd.read_sql("show tables", self.conn)
|
||||
tables = [i[0] for i in data_frame.values.tolist()]
|
||||
style = ttk.Style()
|
||||
self.select_stringVar = StringVar()
|
||||
self.select_stringVar.set(self.table_name)
|
||||
combo = ttk.Combobox(self, width=10, textvariable=self.select_stringVar,font=self.font_style, style="TCombobox")
|
||||
combo["values"] = tables
|
||||
combo.bind('<<ComboboxSelected>>', self.select_value)
|
||||
combo.grid(column=0, row=0)
|
||||
Button(self, text="装载", width=10, command=self.load).grid(column=1, row=0, padx=5)
|
||||
|
||||
def create_tree_widget(self):
|
||||
frame = Frame(self, width=50, height=220)
|
||||
frame.grid(row=1, column=0, columnspan=2, sticky=NSEW, pady=5)
|
||||
frame.grid_columnconfigure(0, weight=1)
|
||||
frame.grid_rowconfigure(0, weight=1)
|
||||
columns = self.data_frame.keys().tolist()
|
||||
style = ttk.Style()
|
||||
style.configure("Custom.Treeview.Heading", font=("宋体", 15))
|
||||
style.configure("Custom.Treeview", rowheight=30, font=("宋体", 15))
|
||||
tree = ttk.Treeview(frame, columns=columns, show="headings", style="Custom.Treeview", selectmode=BROWSE)
|
||||
# 根据dataFrame结构生成表
|
||||
for i in columns:
|
||||
tree.heading(column=i, text=i)
|
||||
for i in columns:
|
||||
tree.column(i, anchor=CENTER, width=80)
|
||||
if columns.index(i) == 1 or columns.index(i) == 0:
|
||||
tree.column(i, anchor=CENTER, width=120)
|
||||
for row in self.data_frame.itertuples():
|
||||
tree.insert(parent="", index=END, values=[row[i] for i in range(1, len(row))])
|
||||
y_scrollbar = ttk.Scrollbar(self, orient='vertical', command=tree.yview)
|
||||
x_scrollbar = ttk.Scrollbar(frame, orient="horizontal", command=tree.xview)
|
||||
tree.configure(yscrollcommand=y_scrollbar.set)
|
||||
tree.config(height=6)
|
||||
tree.grid(row=0, column=0, columnspan=2, sticky=NSEW, pady=5)
|
||||
y_scrollbar.grid(row=1, column=3, sticky='ns')
|
||||
x_scrollbar.grid(row=2, column=0, columnspan=2, sticky='ew')
|
||||
frame.grid_propagate(False)
|
||||
|
||||
def load(self):
|
||||
# 加载数据
|
||||
self.data_frame = pd.read_sql(f"select * from {self.table_name}", self.conn)
|
||||
self.create_tree_widget()
|
||||
|
||||
|
||||
class FormElement(Frame):
|
||||
def __init__(self, master):
|
||||
super().__init__(master)
|
||||
self.master = master
|
||||
self.data = []
|
||||
self.conn = pymysql.connect(user="root", password="cyh0110", 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):
|
||||
self.sid_var = IntVar()
|
||||
self.sname_var = IntVar()
|
||||
self.sclass_var = IntVar()
|
||||
self.ssex_var = IntVar()
|
||||
self.sage_var = IntVar()
|
||||
self.score_var = IntVar()
|
||||
self.courseId_var = IntVar()
|
||||
self.cname_var = IntVar()
|
||||
self.credit_var = IntVar()
|
||||
self.chours_var = IntVar()
|
||||
Label(self, text="学生/student", font=("Lucida Grande", 20), style="inverse").grid(row=0, column=0, sticky=W)
|
||||
Label(self, text="学号", font=self.font_style).grid(row=1, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sid_var).grid(row=1, column=1, sticky=W)
|
||||
self.sid = Entry(self, width=20, font=self.font_style)
|
||||
self.sid.grid(row=1, column=2, sticky=W)
|
||||
Label(self, text="姓名", font=self.font_style).grid(row=1, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sname_var).grid(row=1, column=4, sticky=W)
|
||||
self.sname = Entry(self, width=20, font=self.font_style)
|
||||
self.sname.grid(row=1, column=5, sticky=W)
|
||||
|
||||
Label(self, text="班级", font=self.font_style).grid(row=2, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sclass_var).grid(row=2, column=1, sticky=W)
|
||||
self.sclass = Entry(self, width=20, font=self.font_style)
|
||||
self.sclass.grid(row=2, column=2, sticky=W)
|
||||
Label(self, text="性别", font=self.font_style).grid(row=2, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.ssex_var).grid(row=2, column=4, sticky=W)
|
||||
self.ssex = Entry(self, width=20, font=self.font_style)
|
||||
self.ssex.grid(row=2, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="年龄自", font=self.font_style).grid(row=3, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sage_var).grid(row=3, column=1, sticky=W)
|
||||
self.start_age = Entry(self, width=20, font=self.font_style)
|
||||
self.start_age.grid(row=3, column=2, sticky=W)
|
||||
Label(self, text="到", font=self.font_style).grid(row=3, column=3, sticky=E)
|
||||
Label(self, text="", font=self.font_style).grid(row=3, column=4, sticky=W)
|
||||
self.end_age = Entry(self, width=20, font=self.font_style)
|
||||
self.end_age.grid(row=3, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="课程/course", font=("Lucida Grande", 20), style="inverse").grid(row=4, column=0, sticky=W)
|
||||
Label(self, text="课号", font=self.font_style).grid(row=5, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.courseId_var).grid(row=5, column=1, sticky=W)
|
||||
self.course_id = Entry(self, width=20, font=self.font_style)
|
||||
self.course_id.grid(row=5, column=2, sticky=W)
|
||||
Label(self, text="课名", font=self.font_style).grid(row=5, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.cname_var).grid(row=5, column=4, sticky=W)
|
||||
self.course_name = Entry(self, width=20, font=self.font_style)
|
||||
self.course_name.grid(row=5, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="选课/sc", font=("Lucida Grande", 20), style="inverse").grid(row=6, column=0, sticky=W)
|
||||
Label(self, text="成绩大于", font=self.font_style).grid(row=7, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.score_var).grid(row=7, column=1, sticky=W)
|
||||
self.sc_start = Entry(self, width=20, font=self.font_style)
|
||||
self.sc_start.grid(row=7, column=2, sticky=W)
|
||||
Label(self, text="小于", font=self.font_style).grid(row=7, column=3, sticky=E)
|
||||
Label(self, text="", font=self.font_style).grid(row=7, column=4, sticky=W)
|
||||
self.sc_end = Entry(self, width=20, font=self.font_style)
|
||||
self.sc_end.grid(row=7, 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=8)
|
||||
|
||||
self.sql_text = Text(self, height=3, font=self.font_style, width=75)
|
||||
self.sql_text.grid(row=8, column=0, rowspan=2, columnspan=7, sticky=W)
|
||||
Button(self, text="\n执行SQL\n", command=self.execute_sql, width=8,
|
||||
).grid(column=8, row=8, 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=400)
|
||||
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):
|
||||
sql = "select * from student where 1=1"
|
||||
if self.course_id and self.course_name and self.sc_start and self.sc_end != "":
|
||||
sql = "select * from student s join sc on sc.sid=s.sid join course c on c.cid=sc.cid"
|
||||
if self.sid.get() != "":
|
||||
sql += f" and (s.sid like '{self.sid.get()}')"
|
||||
if self.sname.get() != "":
|
||||
sql += f" and (s.sname like '{self.sname.get()}')"
|
||||
if self.sclass.get() != "":
|
||||
sql += f" and (s.sclass like '{self.sclass.get()}')"
|
||||
if self.ssex.get() != "":
|
||||
sql += f" and (s.ssex like '{self.ssex.get()}')"
|
||||
if self.start_age.get() != "":
|
||||
sql += f" and (s.sage > '{self.start_age.get()}')"
|
||||
if self.end_age.get() != "":
|
||||
sql += f" and (s.sage < '{self.end_age.get()}')"
|
||||
if self.course_id.get() != "":
|
||||
sql += f" and (c.cid like '{self.course_id.get()}')"
|
||||
if self.course_name.get() != "":
|
||||
sql += f" and (c.cname like '{self.course_name.get()}')"
|
||||
if self.sc_start.get() != "":
|
||||
sql += f" and (sc.score > {self.sc_start.get()})"
|
||||
if self.sc_end.get() != "":
|
||||
sql += f" and (sc.score < {self.sc_end.get()})"
|
||||
else:
|
||||
if self.sid.get() != "":
|
||||
sql += f" and (sid like '{self.sid.get()}')"
|
||||
if self.sname.get() != "":
|
||||
sql += f" and (sname like '{self.sname.get()}')"
|
||||
if self.sclass.get() != "":
|
||||
sql += f" and (sclass like '{self.sclass.get()}')"
|
||||
if self.start_age.get() != "":
|
||||
sql += f" and (sage > '{self.start_age.get()}')"
|
||||
if self.end_age.get() != "":
|
||||
sql += f" and (sage < '{self.end_age.get()}')"
|
||||
if sql == "select * from student where 1=1":
|
||||
sql = "select * from student"
|
||||
if (self.sid_var and self.ssex_var and self.sage_var and self.sclass_var and self.sname_var and self.score_var and self.cname_var and self.credit_var and self.chours_var == 0):
|
||||
pass
|
||||
else:
|
||||
data = []
|
||||
data.append("s.sid")if self.sid_var.get() == 1 else ""
|
||||
data.append("s.sname")if self.sname_var.get() == 1 else ""
|
||||
data.append("s.ssex")if self.ssex_var.get() == 1 else ""
|
||||
data.append("s.sage")if self.sage_var.get() == 1 else ""
|
||||
data.append("s.sclass")if self.sclass_var.get() == 1 else ""
|
||||
data.append("sc.score")if self.score_var.get() == 1 else ""
|
||||
data.append("c.cid")if self.courseId_var.get() == 1 else ""
|
||||
data.append("c.cname")if self.cname_var.get() == 1 else ""
|
||||
data.append("c.credit")if self.credit_var.get() == 1 else ""
|
||||
data.append("c.chours")if self.chours_var.get() == 1 else ""
|
||||
sql = sql.replace("select *", f"select {', '.join(data)} ")
|
||||
sql = sql.replace("1=1 and", "")
|
||||
self.sql_text.delete(0.0, END)
|
||||
self.sql_text.insert(1.0, sql)
|
||||
|
||||
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)
|
||||
form_element = FormElement(self.right_frame)
|
||||
form_element.pack(side=TOP, pady=10, anchor=NE)
|
||||
|
||||
|
||||
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()
|
@ -0,0 +1,315 @@
|
||||
from tkinter import Frame, messagebox
|
||||
import tkinter.font as tkFont
|
||||
|
||||
from pandas import DataFrame
|
||||
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
|
||||
|
||||
|
||||
def get_text_content(text):
|
||||
return text.get("0.0", "end").replace("\n", " ")
|
||||
|
||||
|
||||
class LoadElement(Frame):
|
||||
def __init__(self, master, table_name):
|
||||
super().__init__(master)
|
||||
self.master = master
|
||||
self.table_name = table_name
|
||||
self.data = []
|
||||
self.conn = pymysql.connect(user="root", password="cyh0110", database="SCT", host="127.0.0.1", port=3306)
|
||||
self.data_frame = pd.read_sql(f"select * from {self.table_name} limit 0", self.conn)
|
||||
self.font_style = tkFont.Font(family="Lucida Grande", size=20)
|
||||
self.button_font = tkFont.Font(family="Lucida Grande", size=10)
|
||||
self.create_widget()
|
||||
self.select_value(None)
|
||||
self.create_tree_widget()
|
||||
|
||||
def select_value(self, event):
|
||||
self.table_name = self.select_stringVar.get()
|
||||
|
||||
def get_table(self) -> DataFrame:
|
||||
TableList = pd.read_sql("show tables", self.conn)
|
||||
return TableList
|
||||
|
||||
def create_widget(self):
|
||||
data_frame = self.get_table()
|
||||
tables = [i[0] for i in data_frame.values.tolist()]
|
||||
style = ttk.Style()
|
||||
# 设置字体和字体大小
|
||||
style.configure('TCombobox', font=('Arial', 100))
|
||||
self.select_stringVar = StringVar()
|
||||
self.select_stringVar.set(self.table_name)
|
||||
self.combo = ttk.Combobox(self, width=10, height=1, textvariable=self.select_stringVar, font=self.font_style, style="TCombobox")
|
||||
self.combo["values"] = tables
|
||||
self.combo.bind('<<ComboboxSelected>>', self.select_value)
|
||||
self.combo.grid(column=0, row=0)
|
||||
Button(self, text="装载", width=10, command=self.load).grid(column=1, row=0, padx=5)
|
||||
|
||||
def create_tree_widget(self):
|
||||
frame = Frame(self, width=50, height=220)
|
||||
frame.grid(row=1, column=0, columnspan=2, sticky=NSEW, pady=5)
|
||||
frame.grid_columnconfigure(0, weight=1)
|
||||
frame.grid_rowconfigure(0, weight=1)
|
||||
columns = self.data_frame.keys().tolist()
|
||||
style = ttk.Style()
|
||||
style.configure("Custom.Treeview.Heading", font=("宋体", 15))
|
||||
style.configure("Custom.Treeview", rowheight=30, font=("宋体", 15))
|
||||
tree = ttk.Treeview(frame, columns=columns, show="headings", style="Custom.Treeview", selectmode=BROWSE)
|
||||
# 根据dataFrame结构生成表
|
||||
for i in columns:
|
||||
tree.heading(column=i, text=i)
|
||||
for i in columns:
|
||||
tree.column(i, anchor=CENTER, width=80)
|
||||
if columns.index(i) == 1 or columns.index(i) == 0:
|
||||
tree.column(i, anchor=CENTER, width=120)
|
||||
for row in self.data_frame.itertuples():
|
||||
tree.insert(parent="", index=END, values=[row[i] for i in range(1, len(row))])
|
||||
y_scrollbar = ttk.Scrollbar(self, orient='vertical', command=tree.yview)
|
||||
x_scrollbar = ttk.Scrollbar(frame, orient="horizontal", command=tree.xview)
|
||||
tree.configure(yscrollcommand=y_scrollbar.set)
|
||||
tree.config(height=6)
|
||||
tree.grid(row=0, column=0, columnspan=2, sticky=NSEW, pady=5)
|
||||
y_scrollbar.grid(row=1, column=3, sticky='ns')
|
||||
x_scrollbar.grid(row=2, column=0, columnspan=2, sticky='ew')
|
||||
frame.grid_propagate(False)
|
||||
|
||||
def load(self):
|
||||
# 加载数据
|
||||
self.data_frame = pd.read_sql(f"select * from {self.table_name}", self.conn)
|
||||
self.create_tree_widget()
|
||||
|
||||
|
||||
class FormElement(Frame):
|
||||
def __init__(self, master):
|
||||
super().__init__(master)
|
||||
self.master = master
|
||||
self.data = []
|
||||
self.conn = pymysql.connect(user="root", password="cyh0110", 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):
|
||||
self.sid_var = IntVar()
|
||||
self.sname_var = IntVar()
|
||||
self.sclass_var = IntVar()
|
||||
self.ssex_var = IntVar()
|
||||
self.sage_var = IntVar()
|
||||
self.score_var = IntVar()
|
||||
self.courseId_var = IntVar()
|
||||
self.cname_var = IntVar()
|
||||
self.credit_var = IntVar()
|
||||
self.chours_var = IntVar()
|
||||
Label(self, text="学生/student", font=("Lucida Grande", 20), style="inverse").grid(row=0, column=0, sticky=W)
|
||||
Label(self, text="学号", font=self.font_style).grid(row=1, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sid_var).grid(row=1, column=1, sticky=W)
|
||||
self.sid = Entry(self, width=20, font=self.font_style)
|
||||
self.sid.grid(row=1, column=2, sticky=W)
|
||||
Label(self, text="姓名", font=self.font_style).grid(row=1, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sname_var).grid(row=1, column=4, sticky=W)
|
||||
self.sname = Entry(self, width=20, font=self.font_style)
|
||||
self.sname.grid(row=1, column=5, sticky=W)
|
||||
|
||||
Label(self, text="班级", font=self.font_style).grid(row=2, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sclass_var).grid(row=2, column=1, sticky=W)
|
||||
self.sclass = Entry(self, width=20, font=self.font_style)
|
||||
self.sclass.grid(row=2, column=2, sticky=W)
|
||||
Label(self, text="性别", font=self.font_style).grid(row=2, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.ssex_var).grid(row=2, column=4, sticky=W)
|
||||
self.ssex = Entry(self, width=20, font=self.font_style)
|
||||
self.ssex.grid(row=2, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="年龄自", font=self.font_style).grid(row=3, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.sage_var).grid(row=3, column=1, sticky=W)
|
||||
self.start_age = Entry(self, width=20, font=self.font_style)
|
||||
self.start_age.grid(row=3, column=2, sticky=W)
|
||||
Label(self, text="到", font=self.font_style).grid(row=3, column=3, sticky=E)
|
||||
Label(self, text="", font=self.font_style).grid(row=3, column=4, sticky=W)
|
||||
self.end_age = Entry(self, width=20, font=self.font_style)
|
||||
self.end_age.grid(row=3, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="课程/course", font=("Lucida Grande", 20), style="inverse").grid(row=4, column=0, sticky=W)
|
||||
Label(self, text="课号", font=self.font_style).grid(row=5, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.courseId_var).grid(row=5, column=1, sticky=W)
|
||||
self.course_id = Entry(self, width=20, font=self.font_style)
|
||||
self.course_id.grid(row=5, column=2, sticky=W)
|
||||
Label(self, text="课名", font=self.font_style).grid(row=5, column=3, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.cname_var).grid(row=5, column=4, sticky=W)
|
||||
self.course_name = Entry(self, width=20, font=self.font_style)
|
||||
self.course_name.grid(row=5, column=5, sticky=W, pady=10)
|
||||
|
||||
Label(self, text="选课/sc", font=("Lucida Grande", 20), style="inverse").grid(row=6, column=0, sticky=W)
|
||||
Label(self, text="成绩大于", font=self.font_style).grid(row=7, column=0, sticky=E)
|
||||
Checkbutton(self, onvalue=1, offvalue=0, variable=self.score_var).grid(row=7, column=1, sticky=W)
|
||||
self.sc_start = Entry(self, width=20, font=self.font_style)
|
||||
self.sc_start.grid(row=7, column=2, sticky=W)
|
||||
Label(self, text="小于", font=self.font_style).grid(row=7, column=3, sticky=E)
|
||||
Label(self, text="", font=self.font_style).grid(row=7, column=4, sticky=W)
|
||||
self.sc_end = Entry(self, width=20, font=self.font_style)
|
||||
self.sc_end.grid(row=7, 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=8)
|
||||
|
||||
self.sql_text = Text(self, height=3, font=self.font_style, width=75)
|
||||
self.sql_text.grid(row=8, column=0, rowspan=2, columnspan=7, sticky=W)
|
||||
Button(self, text="\n执行SQL\n", command=self.execute_sql, width=8,
|
||||
).grid(column=8, row=8, rowspan=2, padx=10)
|
||||
self.sql_text.insert(1.0, self.default_query_sql)
|
||||
|
||||
def execute_sql(self):
|
||||
cursor = self.conn.cursor()
|
||||
try:
|
||||
sql = get_text_content(self.sql_text).lower().strip()
|
||||
cursor.execute(sql)
|
||||
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()
|
||||
except pymysql.Error as e:
|
||||
messagebox.showerror(str(e.args[0]), str(e.args[1]))
|
||||
finally:
|
||||
cursor.close()
|
||||
|
||||
def create_treeview(self, data_frame):
|
||||
frame = Frame(self, height=400)
|
||||
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):
|
||||
sql = "select * from student where 1=1"
|
||||
if self.course_id and self.course_name and self.sc_start and self.sc_end != "":
|
||||
sql = "select * from student s join sc on sc.sid=s.sid join course c on c.cid=sc.cid"
|
||||
if self.sid.get() != "":
|
||||
sql += f" and (s.sid like '{self.sid.get()}')"
|
||||
if self.sname.get() != "":
|
||||
sql += f" and (s.sname like '{self.sname.get()}')"
|
||||
if self.sclass.get() != "":
|
||||
sql += f" and (s.sclass like '{self.sclass.get()}')"
|
||||
if self.ssex.get() != "":
|
||||
sql += f" and (s.ssex like '{self.ssex.get()}')"
|
||||
if self.start_age.get() != "":
|
||||
sql += f" and (s.sage > '{self.start_age.get()}')"
|
||||
if self.end_age.get() != "":
|
||||
sql += f" and (s.sage < '{self.end_age.get()}')"
|
||||
if self.course_id.get() != "":
|
||||
sql += f" and (c.cid like '{self.course_id.get()}')"
|
||||
if self.course_name.get() != "":
|
||||
sql += f" and (c.cname like '{self.course_name.get()}')"
|
||||
if self.sc_start.get() != "":
|
||||
sql += f" and (sc.score > {self.sc_start.get()})"
|
||||
if self.sc_end.get() != "":
|
||||
sql += f" and (sc.score < {self.sc_end.get()})"
|
||||
else:
|
||||
if self.sid.get() != "":
|
||||
sql += f" and (sid like '{self.sid.get()}')"
|
||||
if self.sname.get() != "":
|
||||
sql += f" and (sname like '{self.sname.get()}')"
|
||||
if self.sclass.get() != "":
|
||||
sql += f" and (sclass like '{self.sclass.get()}')"
|
||||
if self.start_age.get() != "":
|
||||
sql += f" and (sage > '{self.start_age.get()}')"
|
||||
if self.end_age.get() != "":
|
||||
sql += f" and (sage < '{self.end_age.get()}')"
|
||||
if sql == "select * from student where 1=1":
|
||||
sql = "select * from student"
|
||||
if (self.sid_var and self.ssex_var and self.sage_var and self.sclass_var and self.sname_var and self.score_var and self.cname_var and self.credit_var and self.chours_var == 0):
|
||||
pass
|
||||
else:
|
||||
data = []
|
||||
data.append("s.sid")if self.sid_var.get() == 1 else ""
|
||||
data.append("s.sname")if self.sname_var.get() == 1 else ""
|
||||
data.append("s.ssex")if self.ssex_var.get() == 1 else ""
|
||||
data.append("s.sage")if self.sage_var.get() == 1 else ""
|
||||
data.append("s.sclass")if self.sclass_var.get() == 1 else ""
|
||||
data.append("sc.score")if self.score_var.get() == 1 else ""
|
||||
data.append("c.cid")if self.courseId_var.get() == 1 else ""
|
||||
data.append("c.cname")if self.cname_var.get() == 1 else ""
|
||||
data.append("c.credit")if self.credit_var.get() == 1 else ""
|
||||
data.append("c.chours")if self.chours_var.get() == 1 else ""
|
||||
sql = sql.replace("select *", f"select {', '.join(data)} ")
|
||||
sql = sql.replace("1=1 and", "")
|
||||
self.sql_text.delete(0.0, END)
|
||||
self.sql_text.insert(1.0, sql)
|
||||
|
||||
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)
|
||||
form_element = FormElement(self.right_frame)
|
||||
form_element.pack(side=TOP, pady=10, anchor=NE)
|
||||
|
||||
|
||||
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()
|
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
import pandas as pd
|
||||
import pymysql
|
||||
|
||||
conn = pymysql.connect(user="root", password="cyh0110", database="stu_sys", host="127.0.0.1", port=3306)
|
||||
|
||||
data_frame = pd.read_sql("select * from student limit 10", conn)
|
||||
print(data_frame.keys().tolist())
|
||||
for row in data_frame.itertuples():
|
||||
print([row[i] for i in range(1, len(row))])
|
@ -0,0 +1,36 @@
|
||||
import ttkbootstrap as ttk
|
||||
from ttkbootstrap.style import StyleBuilderTTK, Style
|
||||
from ttkbootstrap.tableview import Tableview
|
||||
from ttkbootstrap.constants import *
|
||||
|
||||
app = ttk.Window()
|
||||
app.geometry("400x300")
|
||||
colors = app.style.colors
|
||||
|
||||
coldata = [
|
||||
{"text": "LicenseNumber", "stretch": False},
|
||||
"CompanyName",
|
||||
{"text": "UserCount", "stretch": False},
|
||||
]
|
||||
|
||||
rowdata = [
|
||||
('A123', 'IzzyCo', 12),
|
||||
('A136', 'Kimdee Inc.', 45),
|
||||
('A158', 'Farmadding Co.', 36)
|
||||
]
|
||||
labe = ttk.Labelframe(app, text="fdas")
|
||||
dt = Tableview(
|
||||
master=labe,
|
||||
coldata=coldata,
|
||||
paginated=True,
|
||||
bootstyle=PRIMARY,
|
||||
height=80
|
||||
)
|
||||
dt.insert_rows(END, rowdata)
|
||||
dt.load_table_data()
|
||||
|
||||
ttk.Style().configure("TLabelframe", font="-size 18")
|
||||
|
||||
labe.pack()
|
||||
dt.pack(fill=BOTH, expand=YES, padx=10, pady=10)
|
||||
app.mainloop()
|
Loading…
Reference in new issue