|
|
|
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="Wyz010810", 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.TableList数据展示出来
|
|
|
|
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="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()
|
|
|
|
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):
|
|
|
|
# 创建表单区域
|
|
|
|
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,fields_mapping):
|
|
|
|
"""
|
|
|
|
创建数据列表展示组件
|
|
|
|
:param data_frame:
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
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 = [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: # 通过循环,为每一列设置标题(列名)
|
|
|
|
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(): # 循环遍历 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) # 创建一个垂直滚动条,并将其与树形视图的垂直滚动事件绑定
|
|
|
|
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()
|
|
|
|
|
|
|
|
|
|
|
|
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,
|
|
|
|
"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)
|
|
|
|
root.geometry(alignstr)
|
|
|
|
root.resizable(width=False, height=False)
|
|
|
|
app = StuSys_X2(root, root_attr)
|
|
|
|
|
|
|
|
ttk.Style().configure("TButton", font="-size 18")
|
|
|
|
root.mainloop()
|