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()