diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/StuSystem.iml b/.idea/StuSystem.iml
new file mode 100644
index 0000000..8388dbc
--- /dev/null
+++ b/.idea/StuSystem.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..b010576
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,15 @@
+
+
+
+
+ mysql.8
+ true
+ com.mysql.cj.jdbc.Driver
+ jdbc:mysql://localhost:3306/sct
+ $ProjectFileDir$
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/deployment.xml b/.idea/deployment.xml
new file mode 100644
index 0000000..5f4c1d4
--- /dev/null
+++ b/.idea/deployment.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..95ce354
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..d56657a
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..772d6b3
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/20230101计算思维与程序实践-关系数据库系统项目实践(2).docx b/20230101计算思维与程序实践-关系数据库系统项目实践(2).docx
deleted file mode 100644
index b7688af..0000000
Binary files a/20230101计算思维与程序实践-关系数据库系统项目实践(2).docx and /dev/null differ
diff --git a/BaseWindow.py b/BaseWindow.py
index 8ad33e7..d2d5f67 100644
--- a/BaseWindow.py
+++ b/BaseWindow.py
@@ -13,5 +13,5 @@ class BaseWindow(Frame):
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)
-
+ self.conn = pymysql.connect(user="root", password="Wyz010810", database="SCT", host="127.0.0.1", port=3306)
+ # self.conn = pymysql.connect(user="root", password="123123", database="stu_sys", host="127.0.0.1", port=3306)
diff --git a/Pymysql_Sample.py b/Pymysql_Sample.py
new file mode 100644
index 0000000..8a54c92
--- /dev/null
+++ b/Pymysql_Sample.py
@@ -0,0 +1,17 @@
+import pymysql
+
+if __name__ == '__main__':
+ # 建立数据库连接的语句connection
+ connection = pymysql.connect(user="root", password="Wyz010810", database="SCT", host="127.0.0.1", port=3306)
+ cursor = connection.cursor() # 创建游标
+ sql = "select * from student" # SQL语句字符串
+ # 为了防止SQL注入等安全问题,可以使用参数化查询。
+ try:
+ cursor.execute(sql) # 执行SQL语句
+ ResultList = cursor.fetchall() # 获取游标中的数据
+ print(ResultList) # Student[(S#,Sname,Sage,...),...]
+ except pymysql.Error as e: # 捕获报错信息
+ print("MySQL Error:", e) # 打印报错信息
+ finally:
+ cursor.close() # 关闭游标
+ connection.close() # 关闭数据库连接
diff --git a/X1/StuSys_X1_1.py b/X1/StuSys_X1_1.py
index 87275f3..47232d1 100644
--- a/X1/StuSys_X1_1.py
+++ b/X1/StuSys_X1_1.py
@@ -1,14 +1,14 @@
import pymysql
-def create_database():
+def create_database(conn):
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():
+def create_table(conn):
cursor = conn.cursor() # 创建游标
cursor.execute("USE SCT") # 指定数据库
# 创建student数据表
@@ -50,7 +50,8 @@ def create_table():
if __name__ == '__main__':
- conn = pymysql.connect(user="root", password="cyh0110", host="127.0.0.1", port=3306)
- create_database()
- create_table()
- conn.close() # 关闭链接
+ # conn = pymysql.connect(user="root", password="123456", database="SCT", host="127.0.0.1", port=3306)
+ conn = pymysql.connect(user="root", password="Wyz010810", host="127.0.0.1", port=3306)
+ create_database(conn)
+ create_table(conn)
+ conn.close() # 关闭数据库连接
diff --git a/X1/StuSys_X1_3.py b/X1/StuSys_X1_3.py
index ad71f69..e29ab4e 100644
--- a/X1/StuSys_X1_3.py
+++ b/X1/StuSys_X1_3.py
@@ -8,17 +8,8 @@ last_names_list = last_names.split(",")
course_names = "语文、数学、外语、历史、思想政治、地理、 化学、物理、生物、体育、美术、音乐、技术、微积分、体育、毛泽东思想概论、思想道德修养、高等数学、线性代数、概率论与数理统计、离散数学、计算机原理、人工智能、程序设计基础、面向对象程序设计、数字逻辑电路、电路电子技术、数据结构与算法、WEB程序设计、计算机组成与结构、操作系统、数据库系统原理、编译原理、计算机网络"
course_names_list = course_names.split("、")
-
-# 创建mysql连接
-conn = pymysql.connect(user="root", password="cyh0110", database="SCT", host="127.0.0.1", port=3306)
-# 创建游标
-cursor = conn.cursor()
-
-sid_list = [] # 用于存储生成的sid
-cid_list = [] # 用于存储生成的cid
-
-
-def student_random_record():
+# 随机生成10000条学生表数据
+def student_random_record(conn, cursor):
"""
# 随机生成10000条学生表数据
:return:
@@ -36,11 +27,11 @@ def student_random_record():
sql = f"INSERT INTO student VALUES ('{sid}', '{sname}', '{ssex}', {sage}, '{sclass}')"
cursor.execute(sql)
sid_list.append(sid)
- if num == 2500:
+ if num == 2500: # 每年学生数2500
year += 1
num = 1
class_id = 1
- if class_num == 30:
+ if class_num == 30: # 班级学生数30
class_id += 1
class_num = 1
num += 1
@@ -48,7 +39,7 @@ def student_random_record():
conn.commit()
-def course_random_record():
+def course_random_record(conn, cursor):
"""
随机生成1000条课程表数据
:return:
@@ -56,7 +47,7 @@ def course_random_record():
hours = [i for i in range(8, 192 + 1, 8)]
for i in range(1000):
cid = "%03d" % (i + 1)
- cname = random.choice(course_names_list)
+ cname = random.choice(course_names_list)# course_names_list为样例课程名列表
hour = random.choice(hours)
credit = round(hour / 16, 2)
sql = f"INSERT INTO course (cid, cname, credit, chours) VALUES ('{cid}', '{cname}', {credit}, {hour})"
@@ -65,14 +56,14 @@ def course_random_record():
conn.commit()
-def sc_random_record():
+def sc_random_record(conn, cursor):
"""
随机生成10000 * 30条以上选课表数据
:return:
"""
for sid in sid_list:
year = int(sid[:4]) # 取sid的前四位学年
- for i in range((year - time.localtime().tm_year + 1) * 16):
+ for i in range((year - time.localtime().tm_year + 1) * 16): # 学习课程按学年有16、32、48、64门按学年递增分布
cid = random.choice(cid_list)
score = random.randint(0, 101)
sql = f"INSERT INTO sc(sid, cid, score) VALUES ('{sid}', '{cid}', {score})"
@@ -81,9 +72,15 @@ def sc_random_record():
if __name__ == '__main__':
- student_random_record()
- course_random_record()
- sc_random_record()
+ # 创建mysql连接
+ conn = pymysql.connect(user="root", password="Wyz010810", database="SCT", host="127.0.0.1", port=3306)
+ # 创建游标
+ cursor = conn.cursor()
+ sid_list = [] # 用于存储生成的sid
+ cid_list = [] # 用于存储生成的cid
+ student_random_record(conn, cursor)
+ course_random_record(conn, cursor)
+ sc_random_record(conn, cursor)
# 关闭数据库连接
cursor.close()
conn.close()
\ No newline at end of file
diff --git a/X1/StuSys_X1_4.py b/X1/StuSys_X1_4.py
index f200a45..c9d5682 100644
--- a/X1/StuSys_X1_4.py
+++ b/X1/StuSys_X1_4.py
@@ -1,7 +1,7 @@
import pymysql
# 创建mysql连接(连接并打开数据库)
-conn = pymysql.connect(user="root", password="cyh0110", database="SCT", host="127.0.0.1", port=3306)
+conn = pymysql.connect(user="root", password="Wyz010810", database="SCT", host="127.0.0.1", port=3306)
cursor = conn.cursor() # 游标的定义、打开
# 字符串型SQL语句的执行
SQLString = "INSERT INTO student VALUES ('20220001', '张三', '男', 20, '01')"
diff --git a/X2/StuSys_X2_bootstrap.py b/X2/StuSys_X2_bootstrap.py
index 47179e9..6a1f77e 100644
--- a/X2/StuSys_X2_bootstrap.py
+++ b/X2/StuSys_X2_bootstrap.py
@@ -15,7 +15,7 @@ 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)
+conn = pymysql.connect(user="root", password="Wyz010810", database="SCT", host="127.0.0.1", port=3306)
class LoadElement(Frame):
def __init__(self, master, table_name):
@@ -70,7 +70,7 @@ class LoadElement(Frame):
SQLString = f"select * from {self.table_name}"
# 执行SQL语句 并返回列表数据
self.TableList = pd.read_sql(SQLString, conn)
- # 调用X2界面函数将数据展示出来
+ # 调用X2界面函数将self.TableList数据展示出来
self.create_tree_widget()
@@ -79,12 +79,13 @@ class FormElement(Frame):
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.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))
+ fields_mapping = {'sid': '学号', 'sname': '姓名', 'ssex': '性别', 'sage': '年龄', 'sclass': '班级'}
+ self.create_treeview(pd.read_sql(self.default_query_sql, con=self.conn), fields_mapping)
def create_form(self):
@@ -103,34 +104,37 @@ class FormElement(Frame):
sql = get_text_content(self.sql_text).lower().strip()
print(sql)
- def create_treeview(self, data_frame):
+ def create_treeview(self, data_frame,fields_mapping):
"""
创建数据列表展示组件
:param data_frame:
:return:
"""
- frame = Frame(self, height=700)
+ frame = Frame(self, height=700) # 创建一个 Frame (框架) 组件,作为树形视图的容器
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()
+ # columns = data_frame.keys().tolist()
+ # 使用字段名映射将列名转换为中文
+ columns = [fields_mapping.get(col, col) for col in 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:
+ for i in columns: # 通过循环,为每一列设置标题(列名)
tree.heading(column=i, text=i)
- for i in columns:
+ for i in columns: # 通过循环,为每一列设置列宽
tree.column(i, anchor=CENTER, minwidth=100, width=100)
- for row in data_frame.itertuples():
+ for row in data_frame.itertuples(): # 循环遍历 DataFrame 的每一行,并将数据插入到树形视图中
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)
+ 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)
+ frame.grid_propagate(False) # 禁止框架自动调整其大小以适应其中的内容
class StuSys_X2(BaseWindow):
@@ -158,6 +162,31 @@ class StuSys_X2(BaseWindow):
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()
+
+
if __name__ == '__main__':
"""
minty, lumen, sandstone, yeti, pulse, united, morph, journal, darkly, superhero, solar
@@ -170,8 +199,10 @@ if __name__ == '__main__':
root.columnconfigure(0, weight=1)
root.rowconfigure(1, weight=1)
root_attr = {
- "width": screenwidth * 0.83,
- "height": screenheight * 0.85,
+ # "width": screenwidth * 0.83,
+ # "height": screenheight * 0.85,
+ "width": screenwidth * 0.61,
+ "height": screenheight * 0.63,
}
alignstr = '%dx%d+%d+%d' % (root_attr['width'], root_attr['height'], (screenwidth - root_attr['width']) / 2,
(screenheight - root_attr['height']) / 2)
@@ -180,4 +211,4 @@ if __name__ == '__main__':
app = StuSys_X2(root, root_attr)
ttk.Style().configure("TButton", font="-size 18")
- root.mainloop()
+ root.mainloop()
\ No newline at end of file
diff --git a/X2/__pycache__/StuSys_X2_bootstrap.cpython-37.pyc b/X2/__pycache__/StuSys_X2_bootstrap.cpython-37.pyc
new file mode 100644
index 0000000..d8cb4a0
Binary files /dev/null and b/X2/__pycache__/StuSys_X2_bootstrap.cpython-37.pyc differ
diff --git a/X2/__pycache__/StuSys_X2_bootstrap.cpython-39.pyc b/X2/__pycache__/StuSys_X2_bootstrap.cpython-39.pyc
new file mode 100644
index 0000000..de4214c
Binary files /dev/null and b/X2/__pycache__/StuSys_X2_bootstrap.cpython-39.pyc differ
diff --git a/X3/StuSys_X3_bootstrap.py b/X3/StuSys_X3_bootstrap.py
index e74b1d8..8ae3ecb 100644
--- a/X3/StuSys_X3_bootstrap.py
+++ b/X3/StuSys_X3_bootstrap.py
@@ -24,7 +24,7 @@ class FormElement(Frame):
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.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"
diff --git a/X4/StuSys_X4_bootstrap.py b/X4/StuSys_X4_bootstrap.py
index 37c116c..7015a2c 100644
--- a/X4/StuSys_X4_bootstrap.py
+++ b/X4/StuSys_X4_bootstrap.py
@@ -17,13 +17,12 @@ 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.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"
@@ -36,18 +35,21 @@ class FormElement(Frame):
创建表单
:return:
"""
- self.sid_var = IntVar()
- self.sname_var = IntVar()
- self.sclass_var = IntVar()
- self.ssex_var = IntVar()
- self.sage_var = IntVar()
+ 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 = 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 = 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)
@@ -88,7 +90,7 @@ class FormElement(Frame):
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)
diff --git a/X5/StuSys_X5_11.py b/X5/StuSys_X5_11.py
index 7a54cdb..7e968b8 100644
--- a/X5/StuSys_X5_11.py
+++ b/X5/StuSys_X5_11.py
@@ -17,15 +17,12 @@ 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.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"
@@ -34,21 +31,28 @@ class FormElement(Frame):
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.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()
+
+ # 表明标签:学生/student
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)
@@ -91,14 +95,15 @@ class FormElement(Frame):
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)
-
+ # 配置并创建一个"构造SQL"按钮
Button(self, text="\n\n构造SQL\n\n", command=self.make_sql, width=8,
).grid(column=8, row=0, rowspan=8)
-
+ # 创建一个"执行SQL"按钮,用于执行文本框中的SQL命令
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)
+ # 插入默认的查询SQL
self.sql_text.insert(1.0, self.default_query_sql)
def execute_sql(self):
@@ -141,6 +146,7 @@ class FormElement(Frame):
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查询以包含多个表
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()}')"
@@ -190,9 +196,9 @@ class FormElement(Frame):
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", "")
+ sql = sql.replace("1=1 and", "")# 如果查询条件未改变,则简化查询语句,移除字符串中无用的部分
self.sql_text.delete(0.0, END)
- self.sql_text.insert(1.0, sql)
+ self.sql_text.insert(1.0, sql)# 插入新构造的SQL查询字符串
class StuSys_X4(BaseWindow):
def __init__(self, master, attr):
diff --git a/X5/StuSys_X5_12.py b/X5/StuSys_X5_12.py
index 670a493..725cb89 100644
--- a/X5/StuSys_X5_12.py
+++ b/X5/StuSys_X5_12.py
@@ -22,7 +22,7 @@ class LoadElement(Frame):
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.conn = pymysql.connect(user="root", password="Wyz010810", 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)
@@ -84,7 +84,7 @@ class FormElement(Frame):
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.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"
diff --git a/X5/StuSys_X5_13.py b/X5/StuSys_X5_13.py
index b4d4804..d9b7a54 100644
--- a/X5/StuSys_X5_13.py
+++ b/X5/StuSys_X5_13.py
@@ -12,6 +12,8 @@ from ttkbootstrap.toast import ToastNotification
from BaseWindow import BaseWindow
+import warnings
+warnings.simplefilter(action='ignore', category=UserWarning)
def get_text_content(text):
return text.get("0.0", "end").replace("\n", " ")
@@ -23,7 +25,7 @@ class LoadElement(Frame):
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.conn = pymysql.connect(user="root", password="Wyz010810", 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)
@@ -91,7 +93,7 @@ class FormElement(Frame):
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.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"
diff --git a/X5/StuSys_X5_14.py b/X5/StuSys_X5_14.py
index bfc8f17..2debb56 100644
--- a/X5/StuSys_X5_14.py
+++ b/X5/StuSys_X5_14.py
@@ -8,7 +8,6 @@ from ttkbootstrap.constants import *
import pandas as pd
import pymysql
-from ttkbootstrap.toast import ToastNotification
from BaseWindow import BaseWindow
@@ -22,8 +21,9 @@ class LoadElement(Frame):
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.conn = pymysql.connect(user="root", password="Wyz010810", 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()
@@ -46,11 +46,11 @@ class LoadElement(Frame):
combo["values"] = tables
combo.bind('<>', self.select_value)
combo.grid(column=0, row=0)
- Button(self, text="装载", width=10, command=self.load).grid(column=1, row=0, padx=5)
+ Button(self, text="装载", width=9, command=self.load).grid(column=1, row=0, padx=5)
def create_tree_widget(self):
# 创建画布,用于展示装载后的数据
- frame = Frame(self, width=50, height=180)
+ frame = Frame(self, width=50, height=250)
frame.grid(row=1, column=0, columnspan=2, sticky=NSEW, pady=5)
frame.grid_columnconfigure(0, weight=1)
frame.grid_rowconfigure(0, weight=1)
@@ -88,7 +88,7 @@ class FormElement(Frame):
super().__init__(master)
self.node = node
self.data = []
- self.conn = pymysql.connect(user="root", password="cyh0110", database="SCT", host="127.0.0.1", port=3306)
+ 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.table_names = []
@@ -130,7 +130,13 @@ class FormElement(Frame):
:return: 返回表内的所有字段
"""
data_frame = pd.read_sql(f"desc {self.table_name}", self.conn)
- return data_frame["Field"].tolist()
+ """
+ field_names = []
+ for field in data_frame["Field"]:
+ field_names.append(f"{self.table_name}.{field}")
+ return field_names
+ """
+ return data_frame["Field"].values.tolist()
def create_form(self):
"""
@@ -139,7 +145,7 @@ class FormElement(Frame):
"""
self.select_table_name = StringVar()
self.select_table_name.set(self.table_name)
- combo = ttk.Combobox(self, width=10, height=1, textvariable=self.select_table_name, font=self.font_style,
+ combo = ttk.Combobox(self, width=8, height=1, textvariable=self.select_table_name, font=self.font_style,
style="TCombobox")
combo["values"] = self.table_names
combo.bind('<>', self.select_table)
@@ -166,7 +172,7 @@ class FormElement(Frame):
Button(self, text="构造SQL", command=self.make_sql, width=8, style="custom.TButton"
).grid(column=8, row=0, rowspan=8)
- self.sql_text = Text(self, height=3, font=self.font_style, width=75)
+ self.sql_text = Text(self, height=3, font=self.font_style, width=62)
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)
@@ -195,7 +201,9 @@ class FormElement(Frame):
frame.grid(row=10, column=0, columnspan=10, rowspan=5, sticky=NSEW, pady=10)
frame.grid_columnconfigure(0, weight=1)
frame.grid_rowconfigure(0, weight=1)
- columns = data_frame.keys().tolist()
+ unique_columns = data_frame.columns[~data_frame.columns.duplicated()]
+ columns = unique_columns.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)
@@ -239,6 +247,8 @@ class StuSys_X4(BaseWindow):
def create_left_plate(self):
self.left_frame = Frame(self.master, height=self.attr["height"])
+ self.right_frame = Frame(self.master, height=self.attr["height"])
+ self.right_frame.pack(side=RIGHT, anchor=NW, pady=10, padx=10)
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)
@@ -246,9 +256,9 @@ class StuSys_X4(BaseWindow):
load_element2.pack(side=TOP, pady=10)
load_element2 = LoadElement(self.left_frame, "sc")
load_element2.pack(side=TOP, pady=10)
- message_frame = Frame(self.left_frame, width=50, height=180)
+ message_frame = Frame(self.right_frame, width=50, height=180)
message_frame.pack(side=TOP, pady=10, fill=BOTH)
- self.canvas = Canvas(message_frame, width=50, height=180, bg="#f0f5fa")
+ self.canvas = Canvas(message_frame, width=280, height=1000, bg="#f0f5fa")
self.canvas.configure(background="#f0f5fa")
y_scrollbar = Scrollbar(message_frame, orient="vertical", command=self.canvas.yview)
x_scrollbar = Scrollbar(message_frame, orient="horizontal", command=self.canvas.xview)
@@ -279,10 +289,6 @@ if __name__ == '__main__':
minty, lumen, sandstone, yeti, pulse, united, morph, journal, darkly, superhero, solar
cyborg, vapor, simplex, cerculean,
"""
- from pycallgraph2 import PyCallGraph
- from pycallgraph2.output import GraphvizOutput
- from pycallgraph2 import Config
- from pycallgraph2 import GlobbingFilter
style = "morph"
root = Window(themename=style)
screenwidth = root.winfo_screenwidth()
@@ -290,23 +296,14 @@ if __name__ == '__main__':
root.columnconfigure(0, weight=1)
root.rowconfigure(1, weight=1)
root_attr = {
- "width": screenwidth * 0.83,
- "height": screenheight * 0.85,
+ "width": screenwidth * 0.88,
+ "height": screenheight * 0.90,
}
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)
- output = GraphvizOutput(font_size=30)
- output.output_file = "basic.png"
- output.group_font_size = 40
- config = Config()
- config.trace_filter = GlobbingFilter(include=[
- 'StuSys_X4.*',
- 'FormElement.*',
- 'LoadElement.*',
- ])
- with PyCallGraph(output=output, config=config):
- app = StuSys_X4(root, root_attr)
- ttk.Style().configure("TButton", font="-size 18")
+
+ app = StuSys_X4(root, root_attr)
+ ttk.Style().configure("TButton", font="-size 18")
root.mainloop()
diff --git a/X5/StuSys_X5_15.py b/X5/StuSys_X5_15.py
new file mode 100644
index 0000000..5716eb4
--- /dev/null
+++ b/X5/StuSys_X5_15.py
@@ -0,0 +1,335 @@
+import uuid
+import random
+from tkinter import messagebox
+import tkinter.font as tkFont
+
+from ttkbootstrap import *
+import ttkbootstrap as ttk
+from ttkbootstrap.constants import *
+
+import pandas as pd
+import pymysql
+
+from BaseWindow import BaseWindow
+
+
+import warnings
+warnings.simplefilter(action='ignore', category=UserWarning)
+
+# 添加第三个任务
+
+
+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="Wyz010810", 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()
+ # 设置字体和字体大小
+ style.configure('TCombobox', font=('Arial', 100))
+ self.select_stringVar = StringVar()
+ self.select_stringVar.set(self.table_name)
+ combo = ttk.Combobox(self, width=10, height=1, textvariable=self.select_stringVar, font=self.font_style,
+ style="TCombobox")
+ combo["values"] = tables
+ combo.bind('<>', self.select_value)
+ combo.grid(column=0, row=0)
+ Button(self, text="装载", width=9, command=self.load).grid(column=1, row=0, padx=5)
+
+ def create_tree_widget(self):
+ # 创建画布,用于展示装载后的数据
+ frame = Frame(self, width=50, height=250)
+ 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, node):
+ super().__init__(master)
+ self.node = node
+ 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.table_names = []
+ self.form_content = {}
+ self.get_table_names()
+ self.table_name = self.table_names[0]
+ self.default_query_sql = f"SELECT * FROM {self.table_name}"
+ self.create_form()
+ self.select_table(None)
+ self.create_treeview(pd.read_sql(self.default_query_sql, con=self.conn))
+
+ def get_table_names(self):
+ """
+ 获取该数据库下所有的表
+ :return:
+ """
+ data_frame = pd.read_sql("show tables", self.conn)
+ self.table_names = [i[0] for i in data_frame.values.tolist()]
+
+ def select_table(self, event):
+ """
+ 当下拉框选择表之后,触发该函数,并将tableName改为选择的tableName
+ :param event:
+ :return:
+ """
+ for value in self.form_content.values():
+ value[0].grid_forget()
+ value[2].grid_forget()
+ value[3].grid_forget()
+ self.form_content.clear()
+ self.table_name = self.select_table_name.get()
+ self.create_form()
+ self.sql_text.delete(0.0, END)
+ self.sql_text.insert(1.0, f"SELECT * FROM {self.table_name}")
+
+ def get_field_names(self):
+ """
+ 获取所有数据表的所有字段
+ :return: 返回表内的所有字段
+ """
+ data_frame = pd.read_sql(f"desc {self.table_name}", self.conn)
+ """
+ field_names = []
+ for field in data_frame["Field"]:
+ field_names.append(f"{self.table_name}.{field}")
+ return field_names
+ """
+ return data_frame["Field"].values.tolist()
+
+ def create_form(self):
+ """
+ 创建表单区域,根据数据表自动生成表单
+ :return:
+ """
+ self.select_table_name = StringVar()
+ self.select_table_name.set(self.table_name)
+ combo = ttk.Combobox(self, width=8, height=1, textvariable=self.select_table_name, font=self.font_style,
+ style="TCombobox")
+ combo["values"] = self.table_names
+ combo.bind('<>', self.select_table)
+ combo.grid(column=0, row=0, sticky=W)
+ fields = self.get_field_names()
+ num_fields = len(fields)
+ num_rows = (num_fields + 1) // 2
+ for i in range(num_rows):
+ for j in range(2):
+ field_idx = i * 2 + j
+ if field_idx >= num_fields:
+ break
+ field_name = fields[field_idx]
+ label = Label(self, text=field_name, font=self.font_style)
+ label.grid(row=i + 1, column=j * 2, padx=5, pady=5, sticky=W)
+ checkbutton_var = IntVar()
+ checkbutton = Checkbutton(self, text='', variable=checkbutton_var)
+ checkbutton.grid(row=i + 1, column=j * 2, padx=5, pady=5, sticky=E)
+ entry = Entry(self, font=self.font_style)
+ entry.grid(row=i + 1, column=j * 2 + 1, padx=5, pady=5, sticky=W)
+ self.form_content[field_name] = (entry, checkbutton_var, label, checkbutton)
+ style = Style()
+ style.configure("custom.TButton", padding=(10, 40, 10, 40))
+ Button(self, text="构造SQL", command=self.make_sql, width=8, style="custom.TButton"
+ ).grid(column=8, row=0, rowspan=8)
+
+ self.sql_text = Text(self, height=3, font=self.font_style, width=62)
+ 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()
+ # 获取文本框中的sql语句
+ sql = get_text_content(self.sql_text).lower().strip()
+ try:
+ cursor.execute(sql)
+ # 如果是查询语句
+ if sql.startswith("select"):
+ data_frame = pd.read_sql(sql, con=self.conn)
+ self.create_treeview(data_frame)
+ self.node.message.insert(0, f"{sql}执行成功!共查询到{len(data_frame)}条数据-{uuid.uuid4()}-true") # uuid标识事件的唯一性
+ return
+ # 如果不是查询语句
+ self.node.message.insert(0, f"{sql}执行成功!-{uuid.uuid4()}-true")
+ except pymysql.Error as e:
+ messagebox.showerror(str(e.args[0]), str(e.args[1]))
+ self.node.message.insert(0, f"{sql}执行失败!{e}-{uuid.uuid4()}-false")
+ finally:
+ cursor.close()
+ self.node.update_message()
+
+ def create_treeview(self, data_frame):
+ frame = Frame(self, height=580)
+ frame.grid(row=10, column=0, columnspan=10, rowspan=5, sticky=NSEW, pady=10)
+ frame.grid_columnconfigure(0, weight=1)
+ frame.grid_rowconfigure(0, weight=1)
+ unique_columns = data_frame.columns[~data_frame.columns.duplicated()]
+ columns = unique_columns.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 = f"SELECT * FROM {self.table_name}"
+ conditions = []
+ select_fields = []
+
+ condition_statements = [
+ "{} LIKE '{}'",
+ "{} = '{}'",
+ "NOT ({} != '{}')",
+ "{} IN ('{}')"
+ ]
+
+ for field, (entry, checkbox_var, i, j) in self.form_content.items():
+ if entry.get():
+
+ # conditions.append("{} like '{}'".format(field, entry.get()))
+ # conditions.append("{} = '{}'".format(field, entry.get()))
+ # conditions.append("NOT ({} != '{}')".format(field, entry.get()))
+ # conditions.append("{} IN ('{}')".format(field, entry.get()))
+ conditions.append(random.choice(condition_statements).format(field, entry.get()))
+
+ if checkbox_var.get() == 1:
+ select_fields.append("{}".format(field))
+ if conditions:
+ sql = "SELECT * FROM {} WHERE {}".format(self.table_name, " AND ".join(conditions))
+ print(sql)
+ if select_fields:
+ sql = sql.replace("*", ",".join(select_fields))
+ 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()
+ self.message = []
+
+ def create_left_plate(self):
+ self.left_frame = Frame(self.master, height=self.attr["height"])
+ self.right_frame = Frame(self.master, height=self.attr["height"])
+ self.right_frame.pack(side=RIGHT, anchor=NW, pady=10, padx=10)
+ 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)
+ message_frame = Frame(self.right_frame, width=50, height=180)
+ message_frame.pack(side=TOP, pady=10, fill=BOTH)
+ self.canvas = Canvas(message_frame, width=280, height=1000, bg="#f0f5fa")
+ self.canvas.configure(background="#f0f5fa")
+ y_scrollbar = Scrollbar(message_frame, orient="vertical", command=self.canvas.yview)
+ x_scrollbar = Scrollbar(message_frame, orient="horizontal", command=self.canvas.xview)
+ y_scrollbar.pack(side=RIGHT, fill=BOTH)
+ x_scrollbar.pack(side=BOTTOM, fill=BOTH)
+ self.canvas.pack(side=TOP, fill=BOTH)
+ self.canvas.configure(yscrollcommand=y_scrollbar.set)
+ self.canvas.configure(xscrollcommand=x_scrollbar.set)
+
+ def update_message(self):
+ self.canvas.delete(ALL)
+ for message in self.message:
+ index = self.message.index(message)
+ self.canvas.create_text(0, 20 * index, anchor="nw",
+ text=message.split("-")[0], font=("", 15), fill="black" if message.split("-")[-1] == "true" else "red")
+ self.canvas.update()
+ self.canvas.configure(scrollregion=self.canvas.bbox("all"))
+
+ 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, self)
+ 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.88,
+ "height": screenheight * 0.90,
+ }
+ 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()
diff --git a/X5/StuSys_X5_final.py b/X5/StuSys_X5_final.py
new file mode 100644
index 0000000..af14913
--- /dev/null
+++ b/X5/StuSys_X5_final.py
@@ -0,0 +1,382 @@
+import uuid
+import random
+from tkinter import messagebox
+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
+
+import warnings
+warnings.simplefilter(action='ignore', category=UserWarning)
+
+
+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="123123", database="stu_sys", host="127.0.0.1", port=3306)
+ self.conn = pymysql.connect(user="root", password="Wyz010810", 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.data_frame = pd.DataFrame([]) # 创建一个空的 DataFrame。而不是执行获得并限制返回数量为0
+
+ # 定义字体和按钮的格式
+ 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()
+
+ # 获取下拉框中的table_name以供后续装载等使用
+ def select_value(self, event):
+ self.table_name = self.select_stringVar.get()
+
+ # 固定的版本
+ def create_widget_label(self):
+ # 不再需要查询数据库获取表名,也不需要创建下拉框
+ # data_frame = pd.read_sql("show tables", self.conn)
+ # tables = [i[0] for i in data_frame.values.tolist()]
+
+ style = ttk.Style()
+ # 设置 Label 的字体和字体大小
+ style.configure('TLabel', font=('Arial', 20)) # 根据需要调整字体大小
+
+ # 创建 Label 控件以显示表名
+ label = ttk.Label(self, text=self.table_name, font=self.font_style, style='TLabel')
+ label.grid(column=0, row=0)
+ # 创建装载按钮
+ Button(self, text="装载", width=9, command=self.load).grid(column=1, row=0, padx=5)
+
+ # 创建小控件,包括下拉按钮以及装载按钮
+ 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()
+ # 设置字体和字体大小
+ style.configure('TCombobox', font=('Arial', 100))
+ self.select_stringVar = StringVar()
+ self.select_stringVar.set(self.table_name)
+ combo = ttk.Combobox(self, width=10, height=1, textvariable=self.select_stringVar, font=self.font_style,
+ style="TCombobox")
+ combo["values"] = tables
+ combo.bind('<>', self.select_value)
+ combo.grid(column=0, row=0)
+ Button(self, text="装载", width=9, command=self.load).grid(column=1, row=0, padx=5)
+
+ # 创建一个带有滚动条并定义好样式的树形视图控件,用于显示查询结果
+ def create_tree_widget(self):
+ # 创建画布,用于展示装载后的数据
+ frame = Frame(self, width=50, height=250)
+ 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, node):
+ super().__init__(master)
+ self.node = node
+ self.data = [] # 好像没用到
+ # self.conn = pymysql.connect(user="root", password="123123", database="stu_sys", host="127.0.0.1", port=3306)
+ 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.table_names = [] # 用于存储下拉表单的数据库表名
+ self.form_content = {}
+ self.get_table_names()
+ self.table_name = self.table_names[0]
+ self.default_query_sql = f"SELECT * FROM {self.table_name}"
+ self.create_form()
+ self.select_table(None)
+ self.create_treeview(pd.read_sql(self.default_query_sql, con=self.conn))
+
+
+ def select_table(self, event):
+ """
+ 当下拉框选择表之后,触发该函数,并将tableName改为选择的tableName
+ :param event:
+ :return:
+ """
+ for value in self.form_content.values():
+ value[0].grid_forget()
+ value[2].grid_forget()
+ value[3].grid_forget()
+ self.form_content.clear()
+ self.table_name = self.select_table_name.get()
+ self.create_form()
+ self.sql_text.delete(0.0, END)
+ self.sql_text.insert(1.0, f"SELECT * FROM {self.table_name}")
+
+ def get_table_names(self):
+ """
+ 获取该数据库下所有的表
+ :return:
+ """
+ data_frame = pd.read_sql("show tables", self.conn)
+ self.table_names = [i[0] for i in data_frame.values.tolist()]
+
+ def get_field_names(self):
+ """
+ 获取所有数据表的所有字段
+ :return: 返回表内的所有字段
+ """
+ data_frame = pd.read_sql(f"desc {self.table_name}", self.conn)
+ """
+ field_names = []
+ for field in data_frame["Field"]:
+ field_names.append(f"{self.table_name}.{field}")
+ return field_names
+ """
+ return data_frame["Field"].values.tolist()
+
+ def create_form(self):
+ """
+ 创建表单区域,根据数据表自动生成表单
+ :return:
+ """
+ self.select_table_name = StringVar() # 初始化一个StringVar对象,用于存储当前选中的表名
+ self.select_table_name.set(self.table_name) # 设置默认表名
+ combo = ttk.Combobox(self, width=8, height=1, textvariable=self.select_table_name, font=self.font_style,
+ style="TCombobox") # 创建一个下拉选择框,允许用户选择一个数据表
+ combo["values"] = self.table_names # 设置下拉选项为所有表名
+ combo.bind('<>', self.select_table) # 绑定选择事件处理函数
+ combo.grid(column=0, row=0, sticky=W) # 放置组件
+ # 获取当前表的所有字段名
+ fields = self.get_field_names()
+ num_fields = len(fields)
+ num_rows = (num_fields + 1) // 2 # 计算需要的行数,以每行放置两个字段
+ # 根据字段生成表单元素
+ for i in range(num_rows):
+ for j in range(2): # 每行两列布局
+ field_idx = i * 2 + j
+ if field_idx >= num_fields:
+ break # 如果字段索引超出范围,则退出循环
+ field_name = fields[field_idx] # 获取字段名称
+ # 为每个字段创建一个标签
+ label = Label(self, text=field_name, font=self.font_style)
+ label.grid(row=i + 1, column=j * 2, padx=20, pady=5, sticky=W)
+ # 创建一个复选框,可能用于指示选择状态
+ checkbutton_var = IntVar()
+ checkbutton = Checkbutton(self, text='', variable=checkbutton_var)
+ checkbutton.grid(row=i + 1, column=j * 2, padx=0, pady=5, sticky=E)
+ # 创建一个文本输入框,用于输入或显示字段值
+ entry = Entry(self, font=self.font_style, width=12)
+ # entry = Entry(self, font=self.font_style)
+ entry.grid(row=i + 1, column=j * 2 + 1, padx=5, pady=5, sticky=W)
+ # 存储表单组件引用,以便后续使用
+ self.form_content[field_name] = (entry, checkbutton_var, label, checkbutton)
+ # 配置并创建一个"构造SQL"按钮
+ style = Style()
+ style.configure("custom.TButton", padding=(10, 40, 10, 40))
+ Button(self, text="构造SQL", command=self.make_sql, width=8, style="custom.TButton"
+ ).grid(column=8, row=0, rowspan=8)
+ # 创建一个文本框,用于显示或编辑SQL命令
+ self.sql_text = Text(self, height=3, font=self.font_style, width=46)
+ self.sql_text.grid(row=8, column=0, rowspan=2, columnspan=7, sticky=W)
+ # 创建一个"执行SQL"按钮,用于执行文本框中的SQL命令
+ Button(self, text="\n执行SQL\n", command=self.execute_sql, width=8,
+ ).grid(column=8, row=8, rowspan=2, padx=10)
+ # 插入默认的查询SQL
+ self.sql_text.insert(1.0, self.default_query_sql)
+
+ def execute_sql(self):
+ cursor = self.conn.cursor()
+ sql = get_text_content(self.sql_text).lower().strip() # 获取文本框中的sql语句
+ try:
+ cursor.execute(sql)
+ # 如果是查询语句
+ if sql.startswith("select"):
+ data_frame = pd.read_sql(sql, con=self.conn)
+ self.create_treeview(data_frame)
+ self.node.message.insert(0, f"{sql}执行成功!共查询到{len(data_frame)}条数据-{uuid.uuid4()}-true") # uuid标识事件的唯一性
+ return
+ # 如果不是查询语句
+ self.node.message.insert(0, f"{sql}执行成功!-{uuid.uuid4()}-true")
+ except pymysql.Error as e:
+ # 如果执行过程中遇到pymysql相关错误,则弹出错误信息框
+ messagebox.showerror(str(e.args[0]), str(e.args[1]))
+ self.node.message.insert(0, f"{sql}执行失败!{e}-{uuid.uuid4()}-false")
+ finally:
+ cursor.close()
+ self.node.update_message()
+
+ # 创建一个带有滚动条并定义好样式的树形视图控件,用于显示查询结果
+ def create_treeview(self, data_frame):
+ frame = Frame(self, height=580)
+ frame.grid(row=10, column=0, columnspan=10, rowspan=5, sticky=NSEW, pady=10)
+ # 设置框架的列和行能够随窗口大小调整而伸缩。
+ frame.grid_columnconfigure(0, weight=1)
+ frame.grid_rowconfigure(0, weight=1)
+ unique_columns = data_frame.columns[~data_frame.columns.duplicated()]
+ columns = unique_columns.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 = f"SELECT * FROM {self.table_name}"
+ conditions = []
+ select_fields = []
+
+ condition_statements = [
+ "{} LIKE '{}'",
+ "{} = '{}'",
+ "NOT ({} != '{}')",
+ "{} IN ('{}')"
+ ]
+
+ for field, (entry, checkbox_var, i, j) in self.form_content.items():
+ if entry.get():
+
+ # conditions.append("{} like '{}'".format(field, entry.get()))
+ # conditions.append("{} = '{}'".format(field, entry.get()))
+ # conditions.append("NOT ({} != '{}')".format(field, entry.get()))
+ # conditions.append("{} IN ('{}')".format(field, entry.get()))
+ conditions.append(random.choice(condition_statements).format(field, entry.get()))
+
+ if checkbox_var.get() == 1:
+ select_fields.append("{}".format(field))
+ if conditions:
+ sql = "SELECT * FROM {} WHERE {}".format(self.table_name, " AND ".join(conditions))
+ print(sql)
+ if select_fields:
+ sql = sql.replace("*", ",".join(select_fields))
+ 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()
+ self.message = []
+
+ # 这里创建了左边的三个小的查询的表
+ 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)
+ # ...course与sc的装载表的创建方式类似
+ load_element2 = LoadElement(self.left_frame, "course")
+ load_element2.pack(side=TOP, pady=10)
+ load_element3 = LoadElement(self.left_frame, "sc")
+ load_element3.pack(side=TOP, pady=10)
+
+ # 以下是消息框部分的内容
+
+ # 创建右侧框架并打包定位
+ self.right_frame = Frame(self.master, height=self.attr["height"])
+ self.right_frame.pack(side=RIGHT, anchor=NW, pady=10, padx=10)
+
+ # 创建消息框架和画布,可能用于显示信息或更复杂的交互元素
+ message_frame = Frame(self.right_frame, width=50, height=180)
+ message_frame.pack(side=TOP, pady=10, fill=BOTH)
+ self.canvas = Canvas(message_frame, width=280, height=1000, bg="#f0f5fa")
+ self.canvas.configure(background="#f0f5fa")
+ # 配置滚动条
+ y_scrollbar = Scrollbar(message_frame, orient="vertical", command=self.canvas.yview)
+ x_scrollbar = Scrollbar(message_frame, orient="horizontal", command=self.canvas.xview)
+ y_scrollbar.pack(side=RIGHT, fill=BOTH)
+ x_scrollbar.pack(side=BOTTOM, fill=BOTH)
+ self.canvas.pack(side=TOP, fill=BOTH)
+ self.canvas.configure(yscrollcommand=y_scrollbar.set)
+ self.canvas.configure(xscrollcommand=x_scrollbar.set)
+
+ # 在查询后调用这个函数,更新查询记录部分
+ def update_message(self):
+ self.canvas.delete(ALL)
+ for message in self.message:
+ index = self.message.index(message)
+ self.canvas.create_text(0, 20 * index, anchor="nw",
+ text=message.split("-")[0], font=("", 15),
+ fill="black" if message.split("-")[-1] == "true" else "red")
+ self.canvas.update()
+ self.canvas.configure(scrollregion=self.canvas.bbox("all"))
+
+ 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, self)
+ 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.88,
+ "height": screenheight * 0.90,
+ }
+ 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()
diff --git a/X5/basic.png b/X5/basic.png
new file mode 100644
index 0000000..c0012fe
Binary files /dev/null and b/X5/basic.png differ
diff --git a/__pycache__/BaseWindow.cpython-37.pyc b/__pycache__/BaseWindow.cpython-37.pyc
new file mode 100644
index 0000000..690050e
Binary files /dev/null and b/__pycache__/BaseWindow.cpython-37.pyc differ
diff --git a/__pycache__/BaseWindow.cpython-39.pyc b/__pycache__/BaseWindow.cpython-39.pyc
new file mode 100644
index 0000000..5715200
Binary files /dev/null and b/__pycache__/BaseWindow.cpython-39.pyc differ
diff --git a/draft.py b/draft.py
new file mode 100644
index 0000000..33a7c3e
--- /dev/null
+++ b/draft.py
@@ -0,0 +1,63 @@
+import pymysql
+
+# 创建名为SCT的数据库
+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()
+
+sql = """
+INSERT INTO student VALUES ('20200001', '张三','男',20,'01')
+UPDATE student SET SClass = '02' WHERE S# = '20200001'
+DELETE FROM student WHERE S# = '20200001'
+SELECT * FROM student
+"""
+
+if __name__ == '__main__':
+ conn = pymysql.connect(user="root", password="123456", host="127.0.0.1", port=3306)
+ create_database()
+ create_table()
+ conn.close() # 关闭链接
diff --git a/test.py b/test.py
deleted file mode 100644
index c74d043..0000000
--- a/test.py
+++ /dev/null
@@ -1,9 +0,0 @@
-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))])
diff --git a/test2.py b/test2.py
deleted file mode 100644
index c7ecc0e..0000000
--- a/test2.py
+++ /dev/null
@@ -1,36 +0,0 @@
-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()
\ No newline at end of file