首页 > 编程语言 >python 资源管理工具V1

python 资源管理工具V1

时间:2024-12-30 16:19:28浏览次数:1  
标签:name python self label V1 tk frame table 资源管理

python 资源管理工具V1

资源管理工具V1界面



python 3 环境安装

python -m pip install configparser==5.3.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/ 
python -m pip install pymysql==0.9.3 -i https://pypi.tuna.tsinghua.edu.cn/simple/ 
python -m pip install pyperclip==1.9.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/ 

资源管理工具V1.py

#!/usr/bin/python
# -*- coding:utf-8 -*-
import datetime
import sys,os
import tkinter as tk
import tkinter.ttk as ttk
from tkinter import messagebox
from tkinter import filedialog

try:
    import configparser
except:
    os.popen('python -m pip install configparser==5.3.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/ ')
finally:
    import configparser

try:
    import pymysql
except:
    os.popen('python -m pip install pymysql==0.9.3 -i https://pypi.tuna.tsinghua.edu.cn/simple/ ')
finally:
    import pymysql

try:
    import pyperclip
except:
    os.popen('python -m pip install pyperclip==1.9.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/ ')
finally:
    import pyperclip

"""
pymysql==0.9.3
pyperclip==1.9.0
#tkintertable==1.3.3
#ttkbootstrap==1.10.1
#pyqt5==5.14.2
#pip install ttkbootstrap==1.10.1 -i https://pypi.tuna.tsinghua.edu.cn/simple/

###修改注册表
HKEY_CLASSES_ROOT\.py  ==》 Python.File
HKEY_CLASSES_ROOT\Python.File\Shell\open\command  ==》 "C:\Python37\python.exe" "%1" %*
"""

class Object:
    def __init__(self):
        self.show_tables_search_cache_dict = {}
        self.auth_status = False
        self.auth_username = ""

        if os.name == 'nt':
            userprofile = os.environ.get("userprofile")
        else:
            userprofile = os.environ.get("HOME")
        db_file_name = os.path.basename(os.path.abspath(__file__).replace('.py', '.ini'))
        self.db_config_file = os.path.join(userprofile, db_file_name)

        self.root = tk.Tk()
        self.root.title('IT资源管理系统')
        self.swidth = self.root.winfo_screenwidth() - 10
        self.sheight = self.root.winfo_screenheight() - 75

        self.root.resizable(0, 0)
        ###self.root.geometry('360x240+50+100')将创建一个同样大小的窗口,但其左上角位于屏幕的(50,100)位置
        self.root.geometry(f"{self.swidth}x{self.sheight}+0+0")  # 设置窗口大小
        if os.name == 'nt':
            self.root.iconbitmap("C:\Windows\System32\dfrgui.exe")
        # self.root.update()

        self.init_frame()
        # self.init_menu()
        # # 初始化文本框对象
        # self.text_box = self.init_text_box()
        # self.init_button()
        # self.init_tree()
        # init_text = "Welcome to tkinter."
        # # 初始化标签对象
        # self.label = self.init_label(init_text)

    def error(self,msg):
        messagebox.showinfo("Error", msg)

    def info(self,msg):
        messagebox.showinfo("info", msg)

    def delete_column(self):
        pass
        # for col in self.treeview.columns():
        #     self.treeview.delete(col)

    def login(self, entry_username, entry_password,button_login):
        #print(entry_username, entry_password)
        username = entry_username.get()
        password = entry_password.get()
        ###假设用户名和密码都为'test'进行验证
        if self.user_auth(username, password):
            #print(f"auth ok username:{username} password:{password}")
            entry_username.configure(state="disabled")
            entry_password.configure(state="disabled")
            button_login.configure(state="disabled")
            #self.login_frame.pack_forget()  ##隐藏控件
            ##grid_forget() ##隐藏控件
            # main_frame.pack() ##显示控件
        else:
            messagebox.showwarning("错误", f"用户名或密码错误 username:{username} password:{password}")

    def logout(self, entry_username, entry_password,button_login):
        self.user_auth(entry_username.get(),'')
        entry_username.configure(state="normal", textvariable=tk.StringVar(value=""))
        entry_password.configure(state="normal", textvariable=tk.StringVar(value=""))
        button_login.configure(state="normal")
        self.load_menu_tables('o_modules')  ####加载菜单数据表格

    def user_auth(self,username, password):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            cursor.execute(f"SELECT * FROM o_users where name='{username}' AND password='{password}'")
            results = cursor.fetchall()
            cursor.close()
            self.conn.close()
            if results:
                self.auth_status = True
                self.auth_username = username
                return True
            else:
                self.auth_username = ""
                self.auth_status = False
                return False
        except pymysql.Error as e:
            return False

    def check_user_auth(self,username,table_name):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            cursor.execute(f"SELECT auth_str FROM o_users where name='{username}'")
            results = cursor.fetchall()
            cursor.close()
            self.conn.close()
            table_name_comment = self.get_modules_comment(table_name)
            ##print(f"check_user_auth table_name_comment {table_name_comment}")
            table_auth = False
            for row in results:
                if table_name in row[0].split(',') or table_name_comment in row[0].split(',') or 'ALL' in row[0].split(','):
                    table_auth = True
                    break
            if self.auth_status is True and table_auth is True:
                return True
            else:
                #messagebox.showinfo("Error", "用户权限不足,请先登陆或添加权限!")
                return False
        except pymysql.Error as e:
            #messagebox.showinfo("Error", "用户权限不足,请先登陆或添加权限!")
            return False

    def create_database_if_not_exists(self, database_name):
        try:
            conn, msg = self.db_connect()
            cursor = self.conn.cursor()
            cursor.execute(f"CREATE DATABASE IF NOT EXISTS {database_name} DEFAULT CHARSET utf8")
            conn.commit()
            status = True
            msg = f"Database {database_name} created successfully."
            #print(msg)
            cursor.close()
            self.conn.close()
        except Exception as e:
            status = False
            msg = f"The error '{e}' occurred."
        return status, msg

    def check_db_conn(self):
        try:
            database = self.db_config['database']
            self.conn, msg = self.db_connect()
            #conn.cursor()
            self.conn.close()
            status = True
        except Exception as e:
            try:
                self.db_config['database'] = 'mysql'
                status, msg = self.create_database_if_not_exists(database)
                self.db_config['database'] = database
                if status:
                    self.conn, msg = self.db_connect()
                    self.conn.close()
                    status = True
                else:
                    self.error(msg)
                    status = False
                    msg = str(e)
            except Exception as ee:
                msg = str(ee)
                self.error(msg)
                status = False
        ##print("check_db_conn",self.db_config,status,msg)
        return status,msg

    def set_db_conf(self,host,port,database,user,password):
        # db_config = {
        #     'user': 'root',
        #     'password': 'root.123',
        #     'host': '192.168.1.200',
        #     'port': 3306,
        #     'database': 'itomd',  # 使用mysql数据库来检查数据库是否存在
        # }
        self.db_config = {
            'user': user,
            'password': password,
            'host': host,
            'port': port,
            'database': database
        }
        config = configparser.ConfigParser()
        config['DEFAULT'] = self.db_config
        config['forge.example'] = {}
        with open(self.db_config_file, 'w') as configfile:
            config.write(configfile)

        #########
        # config.read(self.db_config_file, encoding="utf-8")
        # #####获取所有的section
        # #sections = config.sections()
        # print('db_set',host,port,database,user,password)
        # #####修改指定section的值
        # config.set('DEFAULT', 'host', f'{host}')
        # config.write(open(self.db_config_file, 'w'))
        if self.check_db_conn():
            ###删除数据库地址配置框架
            self.init_db_frame.destroy()
            ###初始化数据库
            self.init_db()
            ####加载菜单
            self.load_menu('o_modules')  ####加载菜单
            #####创建内容表单
            self.load_menu_tables('o_modules')  ####加载菜单数据表格

    def db_connect(self):
        try:
            host = self.db_config['host']
            port = int(self.db_config['port'])
            user = self.db_config['user']
            password = self.db_config['password']
            database = self.db_config['database']

            conn = pymysql.connect(host = host,
                port = port,
                user = user,
                password = password,
                database = database)

            msg = f"database {database} conn is  ok"
        except Exception as e:
            conn = None
            msg = f"database {database} connect error ::" + str(e)
        return conn,msg

    def check_tables(self,table_name):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            cursor.execute('show tables')
            tables = cursor.fetchall()
            cursor.close()
            self.conn.close()
            table_list = [table[0] for table in tables]
            return table_name in table_list
        except Exception as e:
            #print(f"check_tables ::{str(e)}")
            return False

    def check_tables_value(self,table_name,field_name,value):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            if type(value) == 'int' :
                cursor.execute(f"select * from {table_name} where {field_name} = {value}")
            else:
                cursor.execute(f"select * from {table_name} where {field_name} = '{value}'")
            results = cursor.fetchall()
            cursor.close()
            self.conn.close()
            if results:
                return True
            else:
                return False
        except pymysql.Error as e:
            messagebox.showinfo("error",f"{e}")
            #print(f"check_tables ::{str(e)}")
            return False

    def check_dbname(self,database_name):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            cursor.execute('''SELECT DATABASE();''')
            dbnames = cursor.fetchall()
            if database_name != dbnames[0][0]:
                cursor.execute(f'use {database_name}')
                self.conn.commit()
            cursor.close()
            self.conn.close()
            return True
        except pymysql.Error as e:
            messagebox.showinfo("error",f"{e}")
            return False

    def exec_sql(self,sql):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            #print(f"执行方法: exec_sql: {sql}")
            cursor = self.conn.cursor()
            cursor.execute(f"{sql}")
            self.conn.commit()
            cursor.close()
            self.conn.close()
            return True
        except Exception as e:
            self.error(f"""exec sql "{sql}" error! ,{e}""")
            return False

    def init_db(self):
        if self.check_tables('o_users') is False:
            #print("检测 o_users 表不存在,正在创建...")
            try:
                sql = "CREATE TABLE IF NOT EXISTS o_users ( id int PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号', name varchar(255) NULL DEFAULT NULL COMMENT '用户名',password varchar(255) NULL DEFAULT NULL COMMENT '密码',auth_str varchar(255) NULL DEFAULT NULL COMMENT '权限') ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '用户管理' ROW_FORMAT = Dynamic;"
                self.exec_sql(sql)
                #print("创建 o_users 表成功")
            except Exception as e:
                self.error("创建 o_users 表时异常", e)

        if self.check_tables_value('o_users','name','admin') is False:
            #print("正在初始化 o_users 表...")
            try:
                sql = "INSERT INTO o_users(name,password,auth_str) VALUES ('admin','admin','ALL')"
                self.exec_sql(sql)
                #print("初始化 o_users 表成功")
            except Exception as e:
                self.error("初始化 o_users 表时异常", e)

        if self.check_tables('o_modules') is False:
            #print("检测 o_modules 表不存在,正在创建...")
            try:
                sql = "CREATE TABLE IF NOT EXISTS o_modules ( id INT PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号', name varchar(255) NULL DEFAULT NULL COMMENT '名称',  comment varchar(255) NULL DEFAULT NULL COMMENT '描述',  fields varchar(255) NULL DEFAULT NULL COMMENT '字段列表') ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '模块管理' ROW_FORMAT = Dynamic;"
                self.exec_sql(sql)
                #print("创建 o_modules 表成功")
            except Exception as e:
                self.error("创建 o_modules 表时异常", e)

        if self.check_tables_value('o_modules','name','o_users') is False:
            #print("正在初始化 o_modules 表...")
            try:
                sql = "INSERT INTO o_modules(name,comment,fields) VALUES ('o_users','用户管理','name,password,auth_str')"
                self.exec_sql(sql)
                #print("初始化 o_modules 表成功")
            except Exception as e:
                self.error("初始化 o_modules 表时异常", e)

    def get_tables_values(self,table_name,filter_value,field_names=[],page=None):
        try:
            #print(f"table_name {table_name} field_names {field_names} filter_value {filter_value}")
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            if len(filter_value) == 0 :
                sql = f"SELECT * FROM {table_name}"
                count_sql = f"select count(*) from {table_name}"
            else:
                if len(field_names) > 0 :
                    sql = f"SELECT * FROM {table_name} where "
                    count_sql = f"select count(*) from {table_name} where "
                    for i,field_name in enumerate(field_names):
                        if i != 0:
                            sql += " or "
                            count_sql += " or "
                        sql += f" {field_name} like '%{filter_value}%'"
                        count_sql += f" {field_name} like '%{filter_value}%'"
                else:
                    sql = f"SELECT * FROM {table_name} where id = {filter_value} "
                    count_sql = f"select count(*) from {table_name}"
            #print(f"get_tables_values {sql} count_sql:{count_sql}")
            if page != None:
                per_page = self.per_page
                offset = (page - 1) * per_page
                sql = sql + f" order by id ASC LIMIT {offset},{per_page} "
                cursor.execute(f"{count_sql}")
                totals_row = cursor.fetchone()[0]
                self.totals_pages = (totals_row // per_page ) + 1
            else:
                self.totals_pages = None
            cursor.execute(f"{sql}")
            results = cursor.fetchall()
            cursor.close()
            self.conn.close()
            return results
        except pymysql.Error as e:
            messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")
            #print(f"加载子菜单数据表格时出错: {e} table_name {table_name} field_names {field_names} filter_value {filter_value}")
            return []

    def get_tables_fields(self,table_name):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            #print(f"执行方法:get_tables_fields , {table_name}")
            cursor.execute(f"show full columns FROM {table_name}")
            columns_info = cursor.fetchall()
            cursor.close()
            self.conn.close()
            fields_dict = {}
            # print(f"show_tables columns_info:{columns_info} ")
            for column_info in columns_info:
                fields_dict[column_info[0]] = column_info[-1]
            return fields_dict
        except pymysql.Error as e:
            messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")
            return None

    def get_tables_fields_str(self,table_name):
        try:
            field_list = list(self.get_tables_fields(table_name).keys())[1:]
            fields = ','.join(field_list)
            return fields
        except pymysql.Error as e:
            messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")
            return None

    def get_modules_name(self,comment):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            cursor.execute(f"select name FROM o_modules where comment = '{comment}'")
            columns_info = cursor.fetchall()
            cursor.close()
            self.conn.close()
            if columns_info:
                return columns_info[0][0]
            else:
                return None
        except pymysql.Error as e:
            messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")
            return None

    def get_modules_comment(self,table_name):
        try:
            self.conn,msg = self.db_connect()  ###连接数据库
            cursor = self.conn.cursor()
            if table_name == 'o_modules':
                cursor.execute(f"select TABLE_COMMENT from INFORMATION_SCHEMA.tables where table_schema = 'itomd' and TABLE_NAME = '{table_name}';")
            else:
                cursor.execute(f"select comment FROM o_modules where name = '{table_name}'")
            results = cursor.fetchall()
            cursor.close()
            self.conn.close()
            #print(f"get_modules_comment results {results} {table_name}")
            if results:
                return results[0][0]
            else:
                return None
        except pymysql.Error as e:
            messagebox.showerror("错误", f"获取model描述时出错: {e}")
            return None

    def reset_add_form(self,obj_list):
        #print(f"reset_add_form ==")
        for obj in obj_list:
            #print(f"reset_add_form {obj.get()}")
            obj.configure(textvariable=tk.StringVar(value=""),state="normal")
        #print(f"reset_add_form ok")

    def save_tables_records(self,table_name,field_list,value_list):
        try:
            #print(f"save_tables_records table_name:{table_name} field_list: {field_list[0]} value_list: {value_list[0]} self.search_entry_id:{self.search_entry_id}")
            if self.check_tables_value(table_name, field_list[0], value_list[0]) is False :
                field_list_str = ",".join(field_list)
                sql = f"INSERT INTO {table_name} ({field_list_str}) VALUES{tuple(value_list)}"
                results = self.exec_sql(sql)
            elif self.check_tables_value(table_name, field_list[0], value_list[0]) is True and self.search_entry_id != "" :
                ##tk.messagebox.showinfo("Error", f"模块 {value_list[0]} 已经存在。")
                field_sql = ""
                for i,field_name in enumerate(field_list[1:]):
                    list_index = i+1
                    if list_index == len(field_list[1:]):
                        field_sql += f"{field_name} = '{value_list[list_index]}' "
                    else:
                        field_sql += f"{field_name} = '{value_list[list_index]}',"
                sql = f"update {table_name} set {field_sql} where {field_list[0]} = '{value_list[0]}'"
                results = self.exec_sql(sql)
                #print(f"save_tables_records sql {sql}")
            else:
                msg = f"模块{self.get_modules_comment(table_name)} 数据 {value_list[0]} 已存在!"
                results = False
            if results is False:
                return False,msg
            else:
                if table_name == 'o_modules':
                    new_table_name = value_list[0]
                    if self.check_tables(value_list[0]) is False :
                        create_sql_fields = ""
                        for field_name in value_list[2].split(','):
                            # value_list.append(obj.get())
                            create_sql_fields += f" {field_name} varchar(255) NULL DEFAULT NULL COMMENT '{field_name}',"
                        sql = f"CREATE TABLE IF NOT EXISTS {new_table_name} ( id int PRIMARY KEY NOT NULL AUTO_INCREMENT COMMENT '序号', {create_sql_fields[0:-1]} ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '{value_list[1]}' ROW_FORMAT = Dynamic;"
                        results = self.exec_sql(sql)
                        #print(f"save_tables_records sql {sql}")
                    elif self.check_tables(value_list[0]) is True and self.search_entry_id != "" :
                        old_field_list = self.get_tables_fields_str(new_table_name).split(',')
                        new_field_list = value_list[2].split(',')
                        create_sql_fields = ""
                        for i,field_name in enumerate(new_field_list):
                            list_index = i + 1
                            if field_name not in old_field_list:
                                create_sql_fields += f"ADD COLUMN {field_name} varchar(255) NULL COMMENT '{field_name}' " # AFTER {field_name}
                                if i != 0:
                                    create_sql_fields += f" AFTER {new_field_list[i - 1]}"  # AFTER {field_name}
                                if list_index != len(new_field_list):
                                    create_sql_fields += ", "
                            else:
                                old_list_index = old_field_list.index(field_name)
                                if i != old_list_index:
                                    create_sql_fields += f"MODIFY COLUMN {field_name} varchar(255) NULL COMMENT '{field_name}' "  # AFTER {field_name}
                                    if i != 0:
                                        create_sql_fields += f" AFTER {new_field_list[i - 1]}"  # AFTER {field_name}
                                    if list_index != len(new_field_list):
                                        create_sql_fields += ", "
                        if len(create_sql_fields) > 0 :
                            sql = f"ALTER TABLE {new_table_name} {create_sql_fields}"
                            results = self.exec_sql(sql)
                            #print(f"save_tables_records sql {sql}")
                    else:
                        msg = f"更新表结构时报错,模块{self.get_modules_comment(table_name)}已经存在!"
                        results = False
                else:
                    msg = "ok"
                    results = True
                if results:
                    msg = "ok"
                return results,msg
        except Exception as e:
            msg = f"更新表结构或数据是报错:{e}"
            return False,msg

    def change_tables_records(self,action,table_name,obj_list):
        try:
            if action == 'add':
                if self.check_user_auth(self.auth_username, table_name) is True:
                    field_list_str = self.get_tables_fields_str(table_name)
                    field_list = field_list_str.split(',')
                    value_list = []
                    for obj in obj_list:
                        value_list.append(obj.get())
                    #print(f"save_add_form self.check_tables_value {table_name}, {field_list[0]}, {value_list[0]}")
                    status ,msg = self.save_tables_records(table_name, field_list, value_list)
                    if status:
                        if table_name == 'o_modules':
                            self.load_menu(table_name)  ####加载菜单
                        self.load_menu_tables(table_name)
                    else:
                        messagebox.showinfo("Error", f"{msg}")
                else:
                    messagebox.showinfo("Error", "用户权限不足,请先登陆或添加权限!")
            else:
                id_str = self.search_entry_id
                #print(f"change_tables_records event action: {action} table_name: {table_name} id_str: {id_str}")
                results = self.get_tables_values(table_name, str(id_str))[0][1:]
                #print(f"change_tables_records results {results} id_str: {id_str}")
                if action == 'edit':
                    self.reset_add_form(obj_list)
                    for i,obj in enumerate(obj_list):
                        obj.configure(textvariable=tk.StringVar(value=results[i]) )
                        if i == 0:
                            obj.configure(state="disabled")
                elif action == 'copy':
                    self.search_entry_id = ""
                    self.reset_add_form(obj_list)
                    for i, obj in enumerate(obj_list):
                        if len(results[i]) >0 :
                            if i == 0 :
                                obj.configure(textvariable=tk.StringVar(value=f"{results[i]}_copy"))
                            else:
                                if table_name == 'o_modules' and  i == 1:
                                    obj.configure(textvariable=tk.StringVar(value=f"{results[i]}_copy"))
                                else:
                                    obj.configure(textvariable=tk.StringVar(value=results[i]))
                elif action == 'delete':
                    if self.check_user_auth(self.auth_username, table_name) is True:
                        #print(f"delete_tables_records table_name: {table_name} id: {id_str}")
                        if table_name == 'o_modules':
                            modules_table_values = self.get_tables_values(table_name, str(id_str))
                            #print(f"delete_tables_records modules_table_values {modules_table_values}")
                            modules_table_name = modules_table_values[0]
                            #print(f"delete_tables_records modules_table_name {modules_table_name}")
                            if self.check_tables(modules_table_name[1]):
                                # sql = f"delete from o_modules where name = '{table_name}'"
                                # self.exec_sql(sql)
                                sql = f"drop table {modules_table_name[1]}"
                                status = self.exec_sql(sql)
                        if self.check_tables_value(table_name, 'id', id_str):
                            sql = f"delete from  {table_name} where id = {id_str}"
                            status = self.exec_sql(sql)
                        if table_name == 'o_modules':
                            self.load_menu(table_name)  ####加载菜单
                        self.load_menu_tables(table_name)
                    else:
                        messagebox.showinfo("Error", "用户权限不足,请先登陆或添加权限!")
        except Exception as e:
            messagebox.showinfo("Error",f"修改表记录出错了,{e}")

    def import_file(self, filename, table_name,create_modules=False):
        try:
            import csv
            with open(filename, mode='r', newline='') as file:
                #print(f"import_file import_data with file")
                reader = csv.reader(file)
                ##print(f"import_file import_data with file reader {reader}")
                file_field_list = ""
                table_field_list = self.get_tables_fields_str(table_name)
                file_field_list_lenght = len(table_field_list.split(','))
                #print(f"import_file import_data table_field_list: {table_field_list}")
                # save_tables_records(self,table_name,field_list,value_list)
                error_list = []
                for i, row in enumerate(reader):
                    #print(f"i {i} row {row} len(row) file_field_list_lenght: {file_field_list_lenght}")
                    tmp_table_name = ""
                    if i == 0:
                        file_field_list = ",".join(row)
                        #print(f"import_or_export_file import_data 0 row : {row} file_field_list: {file_field_list}")
                        if create_modules :
                            if len(row) > 0 :
                                field_list = list(self.get_tables_fields('o_modules').keys())[1:]
                                tmp_table_modules_name = os.path.basename(filename).replace('.csv','')
                                if self.check_tables_value('o_modules','comment',tmp_table_modules_name):
                                    tmp_table_name = self.get_modules_name(tmp_table_modules_name)
                                    self.search_entry_id = tmp_table_name
                                else:
                                    tmp_table_name = datetime.datetime.now().strftime("o_%Y%m%d%H%M")
                                table_field_list = ",".join(row)
                                file_field_list_lenght = len(table_field_list.split(','))
                                value_list = [tmp_table_name,tmp_table_modules_name,table_field_list]
                                results, msg = self.save_tables_records('o_modules', field_list , value_list)

                                if results is False:
                                    return False, f"导入{filename} 的第 {i} 行数据时报错:{msg}"
                                else:
                                    results = self.exec_sql(f"TRUNCATE TABLE {tmp_table_name};")
                    else:
                        if len(row) == file_field_list_lenght:
                            # value_list.append(row)
                            if file_field_list != table_field_list:
                                return False,f"导入数据 {filename}是报错,请检查文件字段名是否和要导入的模块字段名一致!"
                                break
                            else:
                                self.search_entry_id = row[0]
                                if create_modules:
                                    tmp_table_modules_name = os.path.basename(filename).replace('.csv', '')
                                    tmp_table_name = self.get_modules_name(tmp_table_modules_name)
                                    results, msg = self.save_tables_records(tmp_table_name, file_field_list.split(','), row)
                                else:
                                    results, msg = self.save_tables_records(table_name, file_field_list.split(','), row)
                                if results is False:
                                    return False,f"导入{filename} 的第 {i} 行数据时报错:{msg}"
                file.close()
            return True, f"模块 {self.get_modules_comment(table_name)} 导入数据 {filename} 成功!"
        except Exception as e:
            return False, f"模块 {self.get_modules_comment(table_name)} 导入数据是出错了,报错信息:{e}"

    def import_or_export_file(self,import_type,table_name):
        if self.check_user_auth(self.auth_username, table_name) is True:
            if import_type == 'import_modules':
                try:
                    # filetypes = (
                    #     ('csv files', '*.csv'),
                    #     ('All files', '*.*')
                    # )
                    filetypes = (
                        ('csv files', '*.csv'),
                    )
                    filename = filedialog.askopenfilename(title='Open a file', initialdir='/', filetypes=filetypes)
                    if filename:
                        #print(f'import_or_export_file import_data: {filename} table_name: {table_name}')
                        status, msg = self.import_file(filename, table_name,create_modules=True)
                        if status:
                            messagebox.showinfo("INFO", msg)
                        else:
                            messagebox.showinfo("Error", msg)
                    # else:
                    #     messagebox.showinfo("Error", f"导入数据时出错了,请检查文件 '{filename}'.")
                except Exception as e:
                    messagebox.showinfo("Error", f"导入数据时出错了,报错信息:{e}")
                finally:
                    self.load_menu(table_name)  ####加载菜单
                    self.load_menu_tables(table_name)
            elif import_type == 'import_data':
                try:
                    # filetypes = (
                    #     ('csv files', '*.csv'),
                    #     ('All files', '*.*')
                    # )
                    filetypes = (
                        ('csv files', '*.csv'),
                    )
                    filename = filedialog.askopenfilename(title='Open a file', initialdir='/', filetypes=filetypes)
                    if filename:
                        #print(f'import_or_export_file import_data: {filename} table_name: {table_name}')
                        status,msg = self.import_file(filename, table_name)
                        if status:
                            messagebox.showinfo("INFO",msg)
                        else:
                            messagebox.showinfo("Error", msg)
                    # else:
                    #     messagebox.showinfo("Error", f"导入数据时出错了,请检查文件 '{filename}'.")
                except Exception as e:
                    messagebox.showinfo("Error", f"导入数据时出错了,报错信息:{e}")
                finally:
                    self.load_menu_tables(table_name)
            elif import_type == 'export':
                try:
                    import csv
                    fields = self.get_tables_fields_str(table_name).split(',')
                    modules_name = self.get_modules_comment(table_name)
                    filetypes = (
                        ('csv files', '*.csv'),
                    )
                    filename = filedialog.asksaveasfilename(title='save as file',initialdir='/',filetypes=filetypes,initialfile=f'{modules_name}.csv')
                    ##filename = filedialog.askopenfilename(title='Open a file',initialdir='/',filetypes=filetypes)
                    if filename:
                        #print(f'export file: {filename} table_name: {table_name}')
                        with open(filename, mode='w+', newline='') as file:
                            writer = csv.writer(file)
                            writer.writerow(fields)
                            fields_dict = self.get_tables_fields(table_name)
                            field_list = list(fields_dict.keys())
                            if self.search_entry.get() != '':
                                datas = self.get_tables_values(table_name,self.search_entry.get(),fields)
                            else:
                                datas = self.get_tables_values(table_name, '')
                            for row in datas:
                                #print(f'export file: {filename} table_name: {table_name} datas: {datas} row: {row}')
                                writer.writerow(row[1:])
                            file.close()
                        messagebox.showinfo("OK", f"导出数据 {filename} 成功!")
                except Exception as e:
                    messagebox.showinfo("Error",f"导出数据是出错了,{e}")
            elif import_type == 'export_db':
                try:
                    import csv,datetime
                    filetypes = (
                        ('csv files', '*.csv'),
                    )
                    #current_time = datetime.datetime.now().strftime("%Y-%m-%d")
                    #filename = filedialog.asksaveasfilename(title='save as file',initialdir='/',filetypes=filetypes,initialfile=f"{self.db_config['database']}{current_time}.sql")
                    filename = filedialog.asksaveasfilename(title='save as file', initialdir='/', filetypes=filetypes,initialfile=f'IT资源管理数据库备份.csv')
                    if filename:
                        #print(f'export_db: {filename} table_name: {table_name}')
                        #conn = self.db_connect()
                        #cursor = self.conn.cursor()
                        #with open(filename, mode='w+', newline='') as file:
                        with open(filename, mode='w+', newline='') as file:
                            writer = csv.writer(file)
                            modules_fields = self.get_tables_fields_str('o_modules').split(',')
                            modules_values = self.get_tables_values('o_modules', '')
                            writer.writerow(modules_fields)
                            for row in modules_values:
                                writer.writerow(row[1:])
                            ###
                            for row in modules_values:
                                table_values = self.get_tables_values(row[1], '')
                                table_fields = self.get_tables_fields_str(row[1]).split(',')
                                writer.writerow('')
                                writer.writerow([row[2],])
                                writer.writerow(table_fields)
                                for table_row in table_values:
                                    writer.writerow(table_row[1:])
                            file.close()
                        messagebox.showinfo("OK", f"导出数据库 {filename} 成功!")
                except Exception as e:
                    messagebox.showinfo("Error", f"导出数据库时出错了,{e}")
        else:
            messagebox.showinfo("Error", "用户权限不足,请先登陆或添加权限!")

    def show_tables(self,table_name,search_value):
        try:
            #####添加分页框架
            pages_frame = tk.Frame(self.footer_frame, background='white', height=self.pages_frame_height)
            pages_frame.pack(anchor=tk.CENTER, padx=0, pady=0, before=self.footer_label)

            ######创建内容表单,添加表单控件
            table_frame = tk.Frame(self.body_frame, width=self.swidth, height=self.body_height,background="white")  # ,background="white"  background="#cccccc"
            table_frame.pack(expand=True, fill=tk.BOTH, padx=0, pady=0, anchor=tk.CENTER)

            self.search_entry_id = ""
            if search_value == '' and self.search_entry.get() != '' :
                self.search_entry.configure(textvariable=tk.StringVar(value=""))
            fields_dict = self.get_tables_fields(table_name)
            field_list = list(fields_dict.keys())
            results = self.get_tables_values(table_name, search_value ,field_list[1:],page=self.page)
            #print(f"执行方法:show_tables  get_tables_values field_list: {field_list}  field_list1:{field_list[1:]} search_value: {search_value}")
            #field_list.append("control")
            #field_comment_dict["control"] = "控制"
            #table_field_width = int(self.swidth / 8 / len(field_list))

            field_num = len(field_list) -1
            table_col_num=len(field_list)+1
            row_header_width = 60
            row_control_width1 = 150
            if table_name == 'o_modules':
                row_btn_width1 = 145
                row_body_width = self.swidth - row_header_width - row_control_width1 - row_btn_width1
                table_field_width = int(row_body_width / field_num)
                row_control_width = (row_body_width % field_num) + row_control_width1
            else:
                row_body_width = self.swidth - row_header_width - row_control_width1
                table_field_width = int(row_body_width / field_num)
                row_control_width = (row_body_width % field_num) + row_control_width1

            table_label_width = int(table_field_width / 8)
            label_header_width = 8
            label_control_width1 = int(row_control_width / 8 / field_num)
            label_control_width = 12

            str_width = int(self.swidth / 8 / field_num)
            str_width1 = str_width-table_label_width

            # print(f"field_num: {field_num} table_col_num: {table_col_num} "
            #             #       f" table_field_width: {table_field_width} "
            #             #       f" row_header_width: {row_header_width} "
            #             #       f" row_control_width: {row_control_width} "
            #             #       f" table_label_width: {table_label_width} "
            #             #       f" label_control_width1: {label_control_width1}"
            #             #       f" str_width: {str_width}"
            #             #       f" str_width1: {str_width1}")

            if table_name not in self.show_tables_search_cache_dict :
                self.show_tables_search_cache_dict[table_name] = search_value
            elif self.show_tables_search_cache_dict[table_name] != search_value:
                self.show_tables_search_cache_dict[table_name] = search_value

            ####删除所有数据
            #self.table_frame.delete(*self.table_frame.get_children())
            ####创建表格的标题
            add_form_obj_list = []
            for f_col,label in enumerate(fields_dict.keys()):
                if table_name == 'o_modules':
                    c_num = f_col + 1
                    table_col_num = len(field_list)+2
                else:
                    c_num = f_col
                if f_col ==0:
                    ######创建内容表单,添加表单控件
                    t_label_frame_header_1 = tk.Frame(table_frame,background='#A593CE', width=row_header_width)
                    t_label_frame_header_1.grid(row=1, column=f_col, sticky=tk.NSEW, padx=1, pady=1)
                    ######表头 第一列
                    t_label_header_1 = tk.Label(t_label_frame_header_1, text=fields_dict[label] ) ##borderwidth=1,relief='groove'边框  ,width=header_width
                    t_label_header_1.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12), background='#A593CE')  ##wraplength=160
                    t_label_header_1.pack(expand=True, fill=tk.BOTH, padx=1, pady=1, anchor=tk.CENTER)

                    ######表头 最后一列
                    t_label_frame_header_end = tk.Frame(table_frame, background='#A593CE', width=row_control_width)
                    t_label_frame_header_end.grid(row=1, column=table_col_num-1, sticky=tk.NSEW, padx=1, pady=1)
                    ####
                    t_label_header_end = tk.Label(t_label_frame_header_end, text="控制" ,width=label_control_width)  ##borderwidth=1,relief='groove'边框
                    t_label_header_end.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12 ), background='#A593CE')
                    t_label_header_end.pack(expand=True, fill=tk.BOTH, padx=1, pady=1, anchor=tk.CENTER)

                    ########添加表单 第一列
                    t_label_frame_input_1 = tk.Frame(table_frame, background="white", width=row_header_width)
                    t_label_frame_input_1.grid(row=2, column=f_col, sticky=tk.NSEW, padx=1, pady=1)

                    t_label_input_1 = tk.Label(t_label_frame_input_1, text='*')  # , borderwidth=1
                    t_label_input_1.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12),background="white")  ## background="#eeeeee"
                    t_label_input_1.pack(expand=True, fill=tk.BOTH, padx=1, pady=1, anchor=tk.CENTER)

                    ########添加表单 最后一列
                    t_label_frame_input_end = tk.Frame(table_frame ,bd=0, background="white", width=row_control_width)
                    t_label_frame_input_end.grid(row=2, column=table_col_num - 1, padx=1, pady=1, sticky=tk.NSEW)

                    button_add = tk.Button(t_label_frame_input_end, text="添加",command=lambda: self.change_tables_records('add',table_name,add_form_obj_list) ) ##self.save_add_form(table_name, add_form_obj_list)
                    button_add.configure(justify=tk.CENTER, bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 11))
                    button_add.pack(side="left", expand=True, fill=tk.Y, padx=1, pady=3, anchor=tk.CENTER)

                    button_reset = tk.Button(t_label_frame_input_end, text="重置", command=lambda: self.reset_add_form(add_form_obj_list))  # lambda: show_btn()
                    button_reset.configure(justify=tk.CENTER, bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 11))
                    button_reset.pack(side="left", expand=True, fill=tk.Y, padx=1, pady=3, anchor=tk.CENTER )

                    button_add.bind("<Enter>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                    button_add.bind("<Leave>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                    button_reset.bind("<Enter>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                    button_reset.bind("<Leave>", self.mouse_over_event)  # 鼠标指针进入某一组件区域

                    if table_name == 'o_modules':
                        ######创建内容表单,添加表单控件
                        t_label_frame_header_2 = tk.Frame(table_frame, background='#A593CE', width=row_btn_width1)
                        t_label_frame_header_2.grid(row=1, column=c_num, sticky=tk.NSEW, padx=1, pady=1)

                        ###表头 中间字段名
                        t_label_header_2 = tk.Label(t_label_frame_header_2, text='按钮')  ##borderwidth=1,relief='groove'边框  ,width=table_field_width
                        t_label_header_2.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12), background='#A593CE')  ##wraplength=160
                        t_label_header_2.pack(fill=tk.BOTH, expand=True, padx=1, pady=1,anchor=tk.CENTER)  #side="left",

                        ######创建内容表单,添加表单控件
                        t_label_frame_input_2 = tk.Frame(table_frame, background='white', width=row_btn_width1)
                        t_label_frame_input_2.grid(row=2, column=c_num, sticky=tk.NSEW, padx=1, pady=1)

                        # ###表头 中间字段名
                        # t_label_input_2 = tk.Label(t_label_frame_input_2, text='')  ##borderwidth=1,relief='groove'边框  ,width=table_field_width
                        # t_label_input_2.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12,'bold'), background='white')  ##wraplength=160
                        # t_label_input_2.pack(fill=tk.BOTH, expand=True, padx=1, pady=1,anchor=tk.CENTER)  # side="left",
                else:
                    if field_num > 3 and f_col > 4:
                        if field_num in [5,6]:
                            if f_col == 5:
                                table_label_width11 = table_label_width - 2
                            else:
                                table_label_width11 = table_label_width - 3
                        elif field_num in [7,8]:
                            if f_col == 5:
                                table_label_width11 = table_label_width - 1
                            else:
                                table_label_width11 = table_label_width - 2
                        else:
                            if f_col > 5:
                                table_label_width11 = table_label_width - 1
                            else:
                                table_label_width11 = table_label_width
                    else:
                        table_label_width11 = table_label_width
                    ######创建内容表单,添加表单控件
                    t_label_frame_header = tk.Frame(table_frame, background='#A593CE', width=table_field_width)
                    t_label_frame_header.grid(row=1, column=c_num, sticky=tk.NSEW, padx=1, pady=1)

                    ###表头 中间字段名
                    t_label_header = tk.Label(t_label_frame_header, text=fields_dict[label] ,width=table_label_width11)  ##borderwidth=1,relief='groove'边框  ,width=table_field_width
                    t_label_header.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12), background='#A593CE')  ##wraplength=160
                    t_label_header.pack( fill=tk.BOTH, expand=True ,padx=1, pady=1 ,anchor=tk.CENTER)  #side="left",

                    ########添加表单 中间字段名
                    t_label_frame_input = tk.Frame(table_frame, background="white", width=table_field_width)
                    t_label_frame_input.grid(row=2, column=c_num, sticky=tk.NSEW, padx=1, pady=1)

                    t_label_input = tk.Entry(t_label_frame_input,width=table_label_width11)  # , borderwidth=1    ,width=table_field_width
                    t_label_input.configure(bd=2, relief=tk.GROOVE,font=('宋体', 12 ))  # background="#eeeeee"  ,borderwidth=1,border=1
                    t_label_input.pack( fill=tk.BOTH, expand=True ,padx=1, pady=1 ,anchor=tk.CENTER)  #side="left",

                    t_label_input.bind("<Enter>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                    t_label_input.bind("<Leave>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                    add_form_obj_list.append(t_label_input)

                #print(f"show_tables  cloumn:{i} header_width:{header_width} table_field_width:{table_field_width} ")

            self.mouse_event_obj_dict = {}
            #####创建表格的内容
            for row, rowData in enumerate(results):
                row_num = row + 3
                if self.totals_pages is not None:
                    t_label_num = (self.page-1) * self.per_page + row_num-2
                else:
                    t_label_num = row_num - 2
                if row % 2 == 0:
                    row_color='#E7D3B4'
                else:
                    row_color='#eeeeee'
                for col, value in enumerate(rowData):
                    if table_name == 'o_modules':
                        col_num = col+1
                        table_col_num = len(field_list) + 2
                    else:
                        col_num = col
                    if col == 0:
                        t_label_frame_1 = tk.Frame(table_frame, background=row_color, width=row_header_width)
                        t_label_frame_1.grid(row=row_num, column=col, sticky=tk.NSEW,  padx=1, pady=1)

                        ######表格 第一列
                        table_label = tk.Label(t_label_frame_1, text=t_label_num)  # , borderwidth=1  , width=header_width
                        table_label.configure(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12), background=row_color)
                        #table_label.grid(row=row_num, column=col, sticky=tk.NSEW, padx=1, pady=1)  ###side=TOP # 设置标签在窗口的顶端
                        table_label.pack(fill=tk.BOTH, expand=True, padx=1, pady=1,anchor=tk.CENTER)  #side="left",

                        ######表格 最后列
                        t_label_frame_end = tk.Frame(table_frame,background=row_color, width=row_control_width)
                        t_label_frame_end.grid(row=row_num, column=table_col_num-1, padx=1, pady=1, sticky=tk.NSEW)

                        button_edit = tk.Button(t_label_frame_end, text="编辑" ,command=lambda :self.change_tables_records('edit',table_name,add_form_obj_list)) #command=lambda :self.edit_tables_records('edit',table_name, f"{rowData[0]}" ,add_form_obj_list)
                        button_edit.configure(justify=tk.CENTER, bd=1, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 11) ,repeatdelay=1000000 ,repeatinterval=f"{rowData[0]}")
                        button_edit.pack(side="left", fill=tk.Y, expand=True, padx=1, pady=3)

                        button_cp = tk.Button(t_label_frame_end, text="复制" ,command=lambda :self.change_tables_records('copy',table_name,add_form_obj_list))  # command=lambda :self.edit_tables_records('copy',table_name, f"{rowData[0]}" ,add_form_obj_list)
                        button_cp.configure(justify=tk.CENTER, bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 11) ,repeatdelay=1000000 ,repeatinterval=f"{rowData[0]}")
                        button_cp.pack(side="left", fill=tk.Y, expand=True, padx=1, pady=3)  ###side="left",fill=tk.Y,

                        button_del = tk.Button(t_label_frame_end, text="删除" ,command=lambda :self.change_tables_records('delete',table_name,add_form_obj_list))  # lambda: show_btn() command=lambda :self.delete_tables_records(table_name, f"{rowData[0]}")
                        button_del.configure(justify=tk.CENTER,  bd=1, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 11) ,repeatdelay=1000000 ,repeatinterval=f"{rowData[0]}")
                        button_del.pack(side="left", fill=tk.Y, expand=True, padx=1,pady=3) #fill=tk.Y,

                        button_edit.bind("<Enter>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        button_edit.bind("<Leave>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        button_cp.bind("<Enter>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        button_cp.bind("<Leave>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        button_del.bind("<Enter>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        button_del.bind("<Leave>", self.mouse_over_event)  # 鼠标指针进入某一组件区域

                        button_edit.bind("<Button-1>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        button_cp.bind("<Button-1>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        button_del.bind("<Button-1>", self.mouse_over_event)  # 鼠标指针进入某一组件区域

                        if table_name == 'o_modules' and rowData[1] == 'o_users':
                            button_del.configure(state="disabled")
                        elif table_name == 'o_users' and rowData[1] == 'admin':
                            button_del.configure(state="disabled")

                        if table_name == 'o_modules':
                            ######创建内容表单,添加表单控件
                            t_label_frame_2 = tk.Frame(table_frame, background=row_color, width=row_btn_width1)
                            t_label_frame_2.grid(row=row_num, column=col_num, sticky=tk.NSEW, padx=1, pady=1)

                            ##messagebox.showinfo("info", f"rowData: {rowData}  load_menu_tables table_name :{rowData[1]}")
                            ####font=('宋体', 12,'bold')
                            button_module = tk.Button(t_label_frame_2, text=rowData[2], command=lambda: self.on_option_selected(f"{rowData[1]}"))  # lambda: show_btn()
                            button_module.configure(justify=tk.CENTER,  bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12),repeatdelay=1000000, repeatinterval=f"{rowData[0]}")  ##wraplength=160
                            button_module.pack(fill=tk.BOTH, expand=True, padx=1, pady=1)  #side="left",
                            # ######绑定回车事件
                            button_module.bind("<Enter>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                            button_module.bind("<Leave>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                            button_module.bind("<Button-1>", self.mouse_over_event)  # 鼠标双击左键
                    else:
                        if field_num > 3 and col >4:
                            if field_num in [5, 6]:
                                if col == 5:
                                    table_label_width11 = table_label_width - 2
                                else:
                                    table_label_width11 = table_label_width - 3
                            elif field_num in [7, 8]:
                                if col == 5:
                                    table_label_width11 = table_label_width - 1
                                else:
                                    table_label_width11 = table_label_width - 2
                            else:
                                if col > 5:
                                    table_label_width11 = table_label_width - 1
                                else:
                                    table_label_width11 = table_label_width
                        else:
                            table_label_width11 = table_label_width
                        #print(f"show_tables row:{row}  col:{col}  table_label_width11: {table_label_width11} table_label_width: {table_label_width}")
                        t_label_frame = tk.Frame(table_frame, background=row_color, width=table_field_width)
                        t_label_frame.grid(row=row_num, column=col_num, padx=1, pady=1, sticky=tk.NSEW)

                        ######表格中间字段列
                        t_label = tk.Label(t_label_frame, text=value ,width=table_label_width11) #, borderwidth=1  ,width=table_field_width , width=table_field_width

                        if value.startswith('http://') or value.startswith('https://'):
                            #####font=('宋体', 12,'bold','italic')  依次表示字体、字号、加粗、倾斜  underline:下划线  italic:倾斜
                            t_label.configure(justify=tk.CENTER, anchor=tk.W ,height=2, bd=0, relief=tk.RIDGE, font=('宋体', 12,'underline'), fg="blue",background=row_color,activebackground=row_color)
                        else:
                            t_label.configure(justify=tk.CENTER, anchor=tk.W, height=2, bd=0, relief=tk.RIDGE,font=('宋体', 12), background=row_color,activebackground=row_color)
                        t_label.pack( fill=tk.BOTH, expand=True, padx=1, pady=1 )  ##side="left",
                        ######绑定回车事件
                        t_label.bind("<Enter>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        t_label.bind("<Leave>", self.mouse_over_event)  # 鼠标指针进入某一组件区域
                        t_label.bind("<Button-1>", self.mouse_over_event)  # 鼠标单击左键
                        t_label.bind("<Motion>", self.mouse_over_event)  # 鼠标移动事件
                        t_label.bind("<Double-1>", self.mouse_over_event_double)  # 鼠标双击事件
                        ##t_label.bind("<Double-Button-1>", self.mouse_over_event)  # 鼠标双击左键
                        ###table_label_obj = self.mouse_event_obj_dict[table_label_1_key_name]
                        ###print(f"table_label_obj.cget {table_label_obj.cget('text')} ")
                        #color = event.widget.cget('bg')
                        #print(f'触发事件的组件: {event.widget}  {event.widget.cget()}')
                    #print(f"show_tables row:{row}  col:{col}")

            #####添加分页按钮
            if self.totals_pages is not None:
                for page_index in range(self.totals_pages):
                    page_num = page_index + 1
                    t_label_gages = tk.Button(pages_frame, text=page_num, command=lambda: self.load_menu_tables(table_name, self.page))
                    t_label_gages.configure(justify=tk.CENTER, bd=0, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 11), width=4, bg="lightblue")
                    t_label_gages.pack(side=tk.LEFT, anchor=tk.CENTER, fill=tk.Y, expand=False, padx=5,pady=3)
                    if self.page == page_num:
                        t_label_gages.configure(state="disabled",background="#eeeeee")  #background="lightblue" #cdeafb #cccccc eeeeee
                    t_label_gages.bind("<Enter>", self.set_page)  # 鼠标指针进入事件
                    t_label_gages.bind("<Leave>", self.set_page)  # 鼠标指针移出事件
                    t_label_gages.bind("<Button-1>", self.set_page)  # 鼠标指针单击事件

            try:
                self.pages_frame.destroy()  ###删除treeview
            except Exception as e:
                pass
            finally:
                ##pages_frame.pack_forget()
                #####添加分页框架
                self.pages_frame = pages_frame
            try:
                self.table_frame.destroy()  ###删除treeview
            except Exception as e:
                pass
            finally:
                ##table_frame.pack_forget()
                ######创建内容表单,添加表单控件
                self.table_frame = table_frame
        except pymysql.Error as e:
            messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")

    def set_page(self, event):
        event_type = event.type
        obj = event.widget
        if event_type == "4":
            #print(f"obj.cget {obj.cget('text')} id {obj.cget('repeatinterval')} event.type {event.type} Double-Button-1 ")  # event.type
            if obj.__class__.__name__ == 'Button':
                self.page = obj.cget('text')
        if event_type == '7': #######鼠标光标进入组件事件
            if obj.__class__.__name__ == 'Button':
                if self.page != obj.cget('text'):
                    obj.configure(background="#cdeafb")
        elif event_type == '8':  #######鼠标光标移出组件事件
            if obj.__class__.__name__ == 'Button':
                if self.page != obj.cget('text'):
                    obj.configure(background="lightblue")

    def mouse_over_event_double(self, event):
        event_type = event.type
        obj = event.widget
        if event_type == "4":
            ####鼠标单击左键事件
            # print(f"obj.cget {obj.cget('text')} id {obj.cget('repeatinterval')} event.type {event.type} Double-Button-1 ")  # event.type
            if obj.__class__.__name__ == 'Label':
                objtext = obj.cget('text')
                if objtext.startswith('http://') or objtext.startswith('https://'):
                    pyperclip.copy(objtext)
                    import webbrowser
                    webbrowser.open(objtext)

    def mouse_over_event(self,event):
        #background = '#98D2F5'
        #background = row_color
        event_type = event.type
        obj =  event.widget
        ##print(f" obj.__class__.__name__  {obj.__class__.__name__ }   event.type {event.type} ")  # event.type
        if event_type == '6':
            ####鼠标光标进入组件事件
            #print(f"obj.cget {obj.cget('text')}  event.type {event.type} Enter")  # event.type
            if obj.__class__.__name__ == 'Label':
                if self.tipwindow:
                    # 更新提示窗口的位置,使其跟随鼠标
                    x = event.x_root + 20
                    y = event.y_root + 20
                    # 更新窗口位置
                    self.tipwindow.geometry("+%d+%d" % (x, y))
        if event_type == '7':
            ####鼠标光标进入组件事件
            #print(f"obj.cget {obj.cget('text')}  event.type {event.type} Enter")  # event.type
            if obj.__class__.__name__ == 'Label':
                obj.configure(background="#98D2F5")
                objtext = obj.cget('text')
                if len(objtext) > 0:
                    x = obj.winfo_rootx() + obj.winfo_width() // 2
                    y = obj.winfo_rooty() + obj.winfo_height()
                    self.tipwindow = tk.Toplevel(obj)
                    self.tipwindow.wm_overrideredirect(True)  # 去边框
                    self.tipwindow.wm_attributes("-topmost", 1)  # 置顶
                    self.tipwindow.wm_geometry("+%d+%d" % (x, y))
                    label = tk.Label(self.tipwindow, text=objtext, bg='#fafdc2', relief=tk.SOLID, borderwidth=1)
                    ##label = tk.Label(self.tipwindow, text=objtext, bg='white', relief=tk.SOLID, borderwidth=1)
                    label.pack(ipadx=1)
            if obj.__class__.__name__ == 'Entry':
                obj.configure(background="#cdeafb")

            if obj.__class__.__name__ == 'Button':
                obj.configure(background="#cdeafb")
                ##obj.configure(background="#98D2F5")
                # obj_bg = obj.cget('fg')
                # if obj_bg == 'gray':
                #     obj.configure(background="#cdeafb",fg=obj_bg)
                # else:
                #     obj.configure(background="#cdeafb")

        elif event_type == '8':
            ####鼠标光标离开组件事件
            #print(f"obj.cget {obj.cget('text')}  event.type {event.type} Leave  obj_bg {obj_bg}")  # event.type
            #print(f"obj.cget height {obj.winfo_height()}  event.type {event.type}")  # event.type  Return
            if obj.__class__.__name__ == 'Label':
                obj_bg = obj.cget('activebackground')
                obj.configure(background=obj_bg)
                if self.tipwindow:
                    self.tipwindow.destroy()
            if obj.__class__.__name__ == 'Entry':
                obj.configure(background="white")

            if obj.__class__.__name__ == 'Button':
                obj.configure(background="#eeeeee")
        elif event_type == "4":
            ####鼠标单击左键事件
            #print(f"obj.cget {obj.cget('text')} id {obj.cget('repeatinterval')} event.type {event.type} Double-Button-1 ")  # event.type
            if obj.__class__.__name__ == 'Label':
                objtext = obj.cget('text')
                pyperclip.copy(objtext)
                # if objtext.startswith('http://') or objtext.startswith('https://') :
                #     pyperclip.copy(objtext)
                #     import webbrowser
                #     webbrowser.open(objtext)
                # else:
                #     pyperclip.copy(objtext)
            if obj.__class__.__name__ == 'Button':
                self.search_entry_id = obj.cget("repeatinterval")
        elif event_type == "2":
            ####鼠标单击左键事件
            #print(f"obj.cget {obj.cget('text')} id {obj.cget('repeatinterval')} event.type {event.type} Button-1 ")  # event.type  Return
            if obj.__class__.__name__ == 'Entry':
                search_value = obj.get()
            if obj.__class__.__name__ == 'Button':
                self.search_entry_id = obj.cget("repeatinterval")

    def load_menu(self,table_name):
        try:
            ####
            menu_frame = tk.Frame(self.header_frame, width=self.swidth, height=self.header_height)
            menu_frame.configure(bd=0)  ## bg="lightblue" ,highlightbackground="white",highlightcolor="white" bg="lightblue",
            menu_frame.pack(fill=tk.BOTH, expand=False, padx=0, pady=0, ipadx=0, ipady=0, side=tk.TOP,anchor=tk.CENTER)
            #self.menu_frame.grid(row=0, column=0,columnspan=12, padx=0, pady=5, ipadx=0, ipady=0, sticky=tk.NSEW)
            # ttk.Separator(win, orient=VERTICAL).pack(fill=Y, side=LEFT)
            ####
            search_frame = tk.Frame(self.header_frame, width=self.swidth, height=self.search_frame_height, bd=1)
            search_frame.configure(bg="lightblue")  # bg="lightblue", bg="#eeeeee"
            search_frame.pack(fill=tk.BOTH, expand=True, padx=0, pady=0, ipadx=0, ipady=0, side=tk.TOP,anchor=tk.CENTER,after=menu_frame)
            #self.search_frame.grid(row=1, column=0,columnspan=12, padx=0, pady=5,ipadx=0, ipady=0, sticky=tk.NSEW)

            sep_bef = ttk.Separator(self.header_frame)
            sep_bef.pack(fill=tk.X, pady=2, before=search_frame)

            sep_aft = ttk.Separator(self.header_frame)
            sep_aft.pack(fill=tk.X, pady=2, after=search_frame)

            ######添加登录表单 ,fg='#0c06fb'
            ####font=('宋体', 10, 'bold')
            self.button_module = tk.Button(menu_frame, text="模块管理", command=lambda: self.load_menu_tables('o_modules'))  # lambda: show_btn()
            self.button_module.configure(justify=tk.CENTER, height=2, bd=1, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12 ,'bold'), bg='#98D2F5')  ##wraplength=160

            self.button_user = tk.Button(menu_frame, text="用户管理", command=lambda: self.load_menu_tables('o_users') )
            self.button_user.configure(justify=tk.CENTER, height=2, bd=1, relief=tk.RIDGE, anchor=tk.CENTER,  font=('宋体', 12,'bold') ,bg='#98D2F5') ##wraplength=160
            ##bg="#98D2F5",highlightcolor="lightblue",activebackground="lightblue",activeforeground="lightblue",

            self.label_username = tk.Label(menu_frame, text="用户名:" )
            self.label_username.configure(justify=tk.CENTER, height=2,  anchor=tk.CENTER,  font=('宋体', 12,'bold'))  ##wraplength=160

            self.entry_username = tk.Entry(menu_frame )
            self.entry_username.configure(bd=2, relief=tk.GROOVE, font=('宋体', 12),width=20 ,bg='white')

            self.label_password = tk.Label(menu_frame, text="密码:")
            self.label_password.configure(justify=tk.CENTER, height=2, anchor=tk.CENTER,  font=('宋体', 12,'bold'))  ##wraplength=160

            self.entry_password = tk.Entry(menu_frame, show="*" )
            self.entry_password.configure(bd=2, relief=tk.GROOVE, font=('宋体', 12),width=20 ,bg='white')

            self.button_login = tk.Button(menu_frame, text="登录", command=lambda: self.login(self.entry_username, self.entry_password,self.button_login) )
            self.button_login.configure(justify=tk.CENTER, height=2, bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12,'bold') ,bg='#98D2F5')  ##wraplength=160

            self.button_logout = tk.Button(menu_frame, text="注销", command=lambda: self.logout(self.entry_username, self.entry_password,self.button_login ) )
            self.button_logout.configure(justify=tk.CENTER, height=2, bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12,'bold') ,bg='#98D2F5')  ##wraplength=160

            self.button_module.pack(side="left", padx=2, pady=2, fill=tk.Y)
            self.button_user.pack(side="left", padx=2, pady=2, fill=tk.Y)
            self.label_username.pack(side="right", padx=2, pady=2, fill=tk.Y)
            self.entry_username.pack(side="right", padx=2, pady=2, fill=tk.Y,before=self.label_username)
            self.label_password.pack(side="right", padx=2, pady=2, fill=tk.Y,before=self.entry_username)
            self.entry_password.pack(side="right", padx=2, pady=2,fill=tk.Y,before=self.label_password)
            self.button_login.pack(side="right", padx=2, pady=2, fill=tk.Y,before=self.entry_password)
            self.button_logout.pack(side="right", padx=2, pady=2, fill=tk.Y,before=self.button_login)

            # cursor = self.conn.cursor()
            #print("执行方法:load_menu ")
            # cursor.execute("SELECT * FROM o_modules where name != 'o_users'")
            # results = cursor.fetchall()
            # cursor.close()
            results = self.get_tables_values('o_modules', '', ['name'])
            menu_choices_dict = {}
            for row in results:
                ##print(row,row[1],row[2])
                if row[1] != 'o_users':
                    menu_choices_dict[row[1]] = row[2]
            #print(f"results: {results} menu_choices_dict: {menu_choices_dict}")

            ###### 绑定回车事件
            self.entry_username.bind("<Return>",lambda event: self.login(self.entry_username, self.entry_password,self.button_login))
            self.entry_password.bind("<Return>",lambda event: self.login(self.entry_username, self.entry_password,self.button_login))
            self.button_module.bind("<Enter>",lambda event: self.button_module.configure(bg='#cdeafb'))  # cbdde8
            self.button_module.bind("<Leave>", lambda event: self.button_module.configure(bg='#98D2F5'))
            self.button_user.bind("<Enter>", lambda event: self.button_user.configure(bg='#cdeafb'))
            self.button_user.bind("<Leave>", lambda event: self.button_user.configure(bg='#98D2F5'))
            self.entry_password.bind("<Enter>", lambda event: self.entry_password.configure(bg='#cdeafb'))
            self.entry_password.bind("<Leave>", lambda event: self.entry_password.configure(bg='white'))
            self.entry_username.bind("<Enter>", lambda event: self.entry_username.configure(bg='#cdeafb'))
            self.entry_username.bind("<Leave>", lambda event: self.entry_username.configure(bg='white'))
            self.button_login.bind("<Enter>", lambda event: self.button_login.configure(bg='#cdeafb'))
            self.button_login.bind("<Leave>", lambda event: self.button_login.configure(bg='#98D2F5'))
            self.button_logout.bind("<Enter>", lambda event: self.button_logout.configure(bg='#cdeafb'))
            self.button_logout.bind("<Leave>", lambda event: self.button_logout.configure(bg='#98D2F5'))

            ###创建一个字符串列表
            self.menu_choices = list(menu_choices_dict.values())
            self.menu_choices.insert(0,"--请选择菜单--")
            ###创建一个变量
            optionmenu_var = tk.StringVar(self.root)
            optionmenu_var.set(self.menu_choices[0])  # 默认值
            ###创建下拉菜单
            self.optionmenu = tk.OptionMenu(menu_frame, optionmenu_var, *self.menu_choices, command=self.on_option_selected)
            self.optionmenu.configure(justify=tk.CENTER, height=2,width=16, bg='#98D2F5' ,bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12 ,'bold')) #relief=tk.GROOVE relief=tk.RIDGE, borderwidth=0 ,highlightthickness=0
            self.optionmenu.pack(side="left", padx=0, pady=0, fill=tk.Y)
            ##### 绑定回车事件
            self.optionmenu.bind("<Enter>", lambda event: self.optionmenu.configure(activebackground='#cdeafb',activeforeground='gray'))
            self.optionmenu.bind("<Leave>", lambda event: self.optionmenu.configure(bg='#98D2F5'))

            # self.menu_style = ttk.Style()
            # self.menu_style.configure("TMenubutton", background="#98D2F5",foreground='black',font=('宋体', 12))
            ####创建一个变量
            # optionmenu_var = tk.StringVar(value="--请选择菜单--")
            # # optionmenu_var.set(self.menu_choices[0])  # 默认值
            # self.menu_choices = list(menu_choices_dict.values())
            # self.menu_choices.insert(0, "--请选择菜单--")
            # print("self.menu_choices",self.menu_choices)
            ####创建下拉菜单
            # self.optionmenu = ttk.OptionMenu(menu_frame,optionmenu_var, *self.menu_choices ,command=self.on_option_selected)
            # self.optionmenu.configure(width=16,textvariable="--请选择菜单--",text=optionmenu_var) #relief=tk.GROOVE relief=tk.RIDGE, borderwidth=0 ,highlightthickness=0
            # self.optionmenu.pack(side="left", padx=0, pady=2, fill=tk.Y)
            # self.optionmenu.bind("<Enter>", lambda event: self.menu_style.configure("TMenubutton", background="#cdeafb",foreground='black',activebackground='#cdeafb'))
            # self.optionmenu.bind("<Leave>", lambda event: self.menu_style.configure("TMenubutton", background="#98D2F5",foreground='black'))

            if table_name not in self.show_tables_search_cache_dict :
                self.show_tables_search_cache_dict[table_name] = ''

            search_test_text = self.show_tables_search_cache_dict[table_name]
            self.search_entry = tk.Entry(search_frame, textvariable=tk.StringVar(value=search_test_text))  ##borderwidth=1,relief=tk.GROOVE  边框  relief=tk.RIDGE
            self.search_entry.configure(justify=tk.LEFT, bd=2, relief=tk.GROOVE, font=('宋体', 11), width=18)
            self.search_entry.pack(side="left", padx=2, pady=5, ipady=2, fill=tk.Y, expand=False)

            self.search_btn_search = tk.Button(search_frame, text="搜索")
            self.search_btn_search.configure(justify=tk.CENTER, height=1, bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12 ),width=8)
            self.search_btn_search.pack(side="left", padx=2, pady=5, ipady=2, fill=tk.Y, expand=False)

            self.search_btn_cls = tk.Button(search_frame, text="清除")
            self.search_btn_cls.configure(justify=tk.CENTER, height=1, bd=1, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12 ),width=8)
            self.search_btn_cls.pack(side="left", padx=2, pady=5 , ipady=2, fill=tk.Y, expand=False)

            ######绑定回车事件
            self.search_entry.bind("<Enter>", self.mouse_over_event)
            self.search_entry.bind("<Leave>", self.mouse_over_event)
            self.search_btn_search.bind("<Enter>", self.mouse_over_event)
            self.search_btn_search.bind("<Leave>", self.mouse_over_event)
            self.search_btn_cls.bind("<Enter>", self.mouse_over_event)
            self.search_btn_cls.bind("<Leave>", self.mouse_over_event)
            ####
            self.search_btn_import_modules = tk.Button(search_frame,text="导入模块")
            self.search_btn_import_modules.configure(justify=tk.CENTER, height=1, bd=1, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12 ))
            self.search_btn_import_modules.pack(side="right", padx=2, pady=5, ipady=2,ipadx=5, fill=tk.Y, expand=False)
            self.search_btn_import_modules.bind("<Enter>", self.mouse_over_event)
            self.search_btn_import_modules.bind("<Leave>", self.mouse_over_event)
            ####
            self.search_btn_import_data = tk.Button(search_frame,text="导入数据" )
            self.search_btn_import_data.configure(justify=tk.CENTER, height=1, bd=1, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12 ))
            self.search_btn_import_data.pack(side="right", padx=2, pady=5, ipady=2,ipadx=5, fill=tk.Y, expand=False,before=self.search_btn_import_modules)
            self.search_btn_import_data.bind("<Enter>", self.mouse_over_event)
            self.search_btn_import_data.bind("<Leave>", self.mouse_over_event)
            ####
            self.search_btn_export = tk.Button(search_frame,text="导出查询数据" )
            self.search_btn_export.configure(justify=tk.CENTER, height=1, bd=1, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12 ))
            self.search_btn_export.pack(side="right", padx=2, pady=5, ipady=2,ipadx=5, fill=tk.Y, expand=False,before=self.search_btn_import_data)
            self.search_btn_export.bind("<Enter>", self.mouse_over_event)
            self.search_btn_export.bind("<Leave>", self.mouse_over_event)
            ####
            self.search_btn_export_db = tk.Button(search_frame,text="导出所有数据" )
            self.search_btn_export_db.configure(justify=tk.CENTER, height=1, bd=1, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12 ))
            self.search_btn_export_db.pack(side="right", padx=2, pady=5, ipady=2,ipadx=5, fill=tk.Y, expand=False,before=self.search_btn_export)
            self.search_btn_export_db.bind("<Enter>", self.mouse_over_event)
            self.search_btn_export_db.bind("<Leave>", self.mouse_over_event)

            try:
                self.menu_frame.destroy()  ###删除treeview
            except Exception as e:
                pass
            finally:
                self.menu_frame = menu_frame

            try:
                self.search_frame.destroy()  ###删除treeview
            except Exception as e:
                pass
            finally:
                self.search_frame = search_frame

            try:
                self.sep_bef.destroy()  ###删除treeview
            except Exception as e:
                pass
            finally:
                self.sep_bef = sep_bef

            try:
                self.sep_aft.destroy()  ###删除treeview
            except Exception as e:
                pass
            finally:
                self.sep_aft = sep_aft
        except Exception as e:
            messagebox.showerror("错误", f"加载菜单列表时出错: {e}")

    def reset_menu(self,table_name):
        if table_name not in self.show_tables_search_cache_dict:
            self.search_entry.configure(textvariable=tk.StringVar(value=""))
            self.show_tables_search_cache_dict[table_name]=""
        else:
            self.search_entry.configure(textvariable=tk.StringVar(value=self.show_tables_search_cache_dict[table_name]))

        if table_name == 'o_modules':
            self.button_module.configure(state="disabled")
            self.button_user.configure(state="normal")
            ###self.optionmenu.configure(textvariable=tk.StringVar(value=self.menu_choices[0]))
            self.optionmenu.configure(textvariable=tk.StringVar(value=self.menu_choices[0]),fg='black')  ####  #98D2F5 浅蓝色  ##cccccc 灰色

            # self.optionmenu.configure(textvariable=tk.StringVar(value=self.menu_choices[0]))
            # self.menu_style.configure("TMenubutton", background="#98D2F5", foreground='black')

        elif table_name == 'o_users':
            self.button_module.configure(state="normal")
            self.button_user.configure(state="disabled")
            ##self.optionmenu.configure(textvariable=tk.StringVar(value=self.menu_choices[0]))
            self.optionmenu.configure(textvariable=tk.StringVar(value=self.menu_choices[0]),fg='black')  ####  #98D2F5 浅蓝色  ##cccccc 灰色

            # self.optionmenu.configure(textvariable=tk.StringVar(value=self.menu_choices[0]))
            # self.menu_style.configure("TMenubutton", background="#98D2F5", foreground='black')
        else:
            self.button_user.configure(state="normal")
            self.button_module.configure(state="normal")
            table_comment_name = self.get_modules_comment(table_name)
            self.optionmenu.configure(textvariable=tk.StringVar(value=table_comment_name), bg='#98D2F5',fg='gray')  ####  #98D2F5 浅蓝色  ##cccccc 灰色

            # self.optionmenu.configure(textvariable=tk.StringVar(value=table_comment_name))
            # self.menu_style.configure("TMenubutton", background="#98D2F5", foreground='gray')

        ###### 绑定回车事件
        # self.search_entry.bind("<Return>", lambda event: self.show_tables(table_name, self.search_entry.get()))
        # self.search_btn_search.configure(command=lambda: self.show_tables(table_name, self.search_entry.get()))
        # self.search_btn_cls.configure(command=lambda: self.show_tables(table_name, ''))
        self.search_entry.bind("<Return>", lambda event: self.show_search_table_values(table_name))
        self.search_btn_search.configure(command=lambda: self.show_search_table_values(table_name))
        self.search_btn_cls.configure(command=lambda: self.show_search_table_values(table_name,''))

        ########绑定导入导出数据库按钮回掉函数
        self.search_btn_import_modules.configure(command=lambda: self.import_or_export_file('import_modules', table_name))
        self.search_btn_import_data.configure(command=lambda: self.import_or_export_file('import_data', table_name))
        self.search_btn_export.configure(command=lambda: self.import_or_export_file('export', table_name))
        self.search_btn_export_db.configure(command=lambda: self.import_or_export_file('export_db', table_name))

    def show_search_table_values(self,table_name,search_value=None):
        if search_value == '':
            self.show_tables_search_cache_dict[table_name] = ''
        else:
            self.show_tables_search_cache_dict[table_name] = self.search_entry.get()
        self.load_menu_tables(table_name)

    def load_menu_tables(self,table_name,page=None):
        ##messagebox.showinfo("info",f"load_menu_tables {table_name}")
        if self.check_user_auth(self.auth_username, table_name) is True or table_name == 'o_modules' :
            self.reset_menu(table_name)
            if page is None:
                self.page = 1
            else:
                self.page = page
            self.show_tables(table_name, self.search_entry.get())
        else:
            messagebox.showinfo("Error", "用户权限不足,请先登陆或添加权限!")

    def on_option_selected(self,selected_value):
        ###messagebox.showinfo("info", f"selected_value {selected_value} self.search_entry_id {self.search_entry_id}")
        if selected_value != '--请选择菜单--' or self.search_entry_id != "" :
            if self.search_entry_id != "":
                table_value = self.get_tables_values('o_modules', str(self.search_entry_id))
                ##messagebox.showinfo("info", f"table_value {table_value} self.search_entry_id {self.search_entry_id}")
                table_name = table_value[0][1]
            else:
                table_name = self.get_modules_name(selected_value)
            ##self.optionmenu.configure(textvariable=tk.StringVar(value=selected_value), bg='#98D2F5',fg='gray')  ####  #98D2F5 浅蓝色  ##cccccc 灰色
            self.load_menu_tables(table_name)

    def load_main_frame_tables(self):
        if os.path.exists(self.db_config_file):
            config = configparser.ConfigParser()
            config.read(self.db_config_file, encoding="utf-8")
            #####修改指定section的值
            ##config.set('section1', 'key1', 'new_value')
            self.db_config = {
                'user': config.get('DEFAULT', 'user'),
                'password': config.get('DEFAULT', 'password'),
                'host': config.get('DEFAULT', 'host'),
                'port': int(config.getint('DEFAULT', 'port')),
                'database': config.get('DEFAULT', 'database'),  # 使用mysql数据库来检查数据库是否存在
            }
            if self.check_db_conn():
                ###初始化数据库
                self.init_db()
                ####加载菜单
                self.load_menu('o_modules')  ####加载菜单
                #####创建内容表单
                self.load_menu_tables('o_modules')  ####加载菜单数据表格
        else:
            init_db_frame = tk.Frame(self.body_frame, width=self.swidth, height=self.body_height)
            init_db_frame.configure(bg="white", height=self.body_height, highlightbackground="#eeeeee",highlightcolor="#eeeeee")  ##,bd=5
            init_db_frame.pack( expand=True, padx=5, pady=5, anchor=tk.CENTER )
            ###fill=tk.BOTH,
            #####side=tk.RIGHT, side=tk.TOP,  side=tk.BOTTOM,
            ####anchor ["nw", "n", "ne", "w", "center", "e", "sw", "s", "se"]
            ####justify: Literal["left", "center", "right"]

            self.label_title = tk.Label(init_db_frame, text="Mysql数据库配置")
            self.label_title.configure(justify=tk.RIGHT, height=2, anchor=tk.CENTER,font=('宋体', 18, 'bold'))  ##wraplength=160

            self.label_db_host = tk.Label(init_db_frame, text="数据库地址:")
            self.label_db_host.configure(justify=tk.RIGHT, height=2, anchor=tk.E,font=('宋体', 12, 'bold'))  ##wraplength=160

            self.entry_db_host = tk.Entry(init_db_frame)
            self.entry_db_host.configure(bd=2, relief=tk.GROOVE, font=('宋体', 12), width=30, bg='white')

            self.label_db_port = tk.Label(init_db_frame, text="数据库端口:")
            self.label_db_port.configure(justify=tk.RIGHT, height=2, anchor=tk.E ,font=('宋体', 12, 'bold'))  ##wraplength=160

            self.entry_db_port = tk.Entry(init_db_frame )
            self.entry_db_port.configure(bd=2, relief=tk.GROOVE, font=('宋体', 12), width=30, bg='white')

            self.label_db_name = tk.Label(init_db_frame, text="数据库名称:")
            self.label_db_name.configure(justify=tk.RIGHT, height=2, anchor=tk.E,font=('宋体', 12, 'bold'))  ##wraplength=160

            self.entry_db_name = tk.Entry(init_db_frame)
            self.entry_db_name.configure(bd=2, relief=tk.GROOVE, font=('宋体', 12), width=30, bg='white')

            self.label_db_username = tk.Label(init_db_frame, text="用 户 名:")
            self.label_db_username.configure(justify=tk.RIGHT, height=2, anchor=tk.E ,font=('宋体', 12, 'bold'))  ##wraplength=160

            self.entry_db_username = tk.Entry(init_db_frame)
            self.entry_db_username.configure(bd=2, relief=tk.GROOVE, font=('宋体', 12), width=30, bg='white')

            self.label_db_password = tk.Label(init_db_frame, text="密    码:")
            self.label_db_password.configure(justify=tk.RIGHT, height=2, anchor=tk.E , font=('宋体', 12, 'bold'))  ##wraplength=160

            self.entry_db_password = tk.Entry(init_db_frame, show="*")
            self.entry_db_password.configure(bd=2, relief=tk.GROOVE, font=('宋体', 12), width=30, bg='white')

            self.button_db_init = tk.Button(init_db_frame, text="连接并保存设置",command=lambda: self.set_db_conf(self.entry_db_host.get(),self.entry_db_port.get(),self.entry_db_name.get(),self.entry_db_username.get(), self.entry_db_password.get()))
            self.button_db_init.configure(justify=tk.CENTER, height=2, bd=1, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12, 'bold'))  ##wraplength=160

            self.label_title.grid(row=0, column=5, columnspan=2, padx=1, pady=1, sticky=tk.NSEW)
            self.label_db_host.grid(row=1, column=5, padx=1, pady=1, sticky=tk.NSEW)
            self.entry_db_host.grid(row=1, column=6, padx=1, pady=1, sticky=tk.NSEW)
            self.label_db_port.grid(row=2,column=5, padx=1, pady=1, sticky=tk.NSEW)
            self.entry_db_port.grid(row=2, column=6, padx=1, pady=1, sticky=tk.NSEW)
            self.label_db_name.grid(row=3, column=5, padx=1, pady=1, sticky=tk.NSEW)
            self.entry_db_name.grid(row=3, column=6, padx=1, pady=1, sticky=tk.NSEW)
            self.label_db_username.grid(row=4, column=5, padx=1, pady=1, sticky=tk.NSEW)
            self.entry_db_username.grid(row=4, column=6, padx=1, pady=1, sticky=tk.NSEW)
            self.label_db_password.grid(row=5, column=5, padx=1, pady=1, sticky=tk.NSEW)
            self.entry_db_password.grid(row=5, column=6, padx=1, pady=1, sticky=tk.NSEW)
            self.button_db_init.grid(row=6, column=5, columnspan=2,padx=1, pady=1, sticky=tk.NSEW)

            self.entry_db_host.bind("<Enter>", self.mouse_over_event)
            self.entry_db_host.bind("<Leave>", self.mouse_over_event)  ##bg='#98D2F5'
            self.entry_db_port.bind("<Enter>", self.mouse_over_event)
            self.entry_db_port.bind("<Leave>", self.mouse_over_event)  ##bg='#98D2F5'
            self.entry_db_name.bind("<Enter>", self.mouse_over_event)
            self.entry_db_name.bind("<Leave>", self.mouse_over_event)  ##bg='#98D2F5'
            self.entry_db_username.bind("<Enter>", self.mouse_over_event)
            self.entry_db_username.bind("<Leave>", self.mouse_over_event)  ##bg='#98D2F5'
            self.entry_db_password.bind("<Enter>", self.mouse_over_event)
            self.entry_db_password.bind("<Leave>", self.mouse_over_event)  ##bg='#98D2F5'
            self.button_db_init.bind("<Enter>", lambda event: self.button_db_init.configure(bg='#cdeafb'))
            self.button_db_init.bind("<Leave>", lambda event: self.button_db_init.configure(bg='#eeeeee')) ##bg='#98D2F5'

            self.init_db_frame = init_db_frame

    def init_frame(self):
        self.main_frame = tk.Frame(self.root)
        self.main_frame.pack(side=tk.TOP, fill=tk.BOTH,expand=True,padx=15,pady=1)
        # 打包几何管理器的各个选项细节
        # side:决定获得剩余空间的某一侧(可选LEFT,RIGHT,TOP,BOTTOM),默认为TOP;
        # expand:拓冲分配所得空间(可选NO,YES),默认为NO;
        # fill:填充分配所得空间(可选Y,X,BOTH),默认为None;
        # anchor:定位组件在分配所得空间中的位置(默认为CENTER;可选N,S,W,E,NW,NE,SW,SE),默认为CENTER。
        ##border: gray
        ##relief 	设置边框样式, 有falt, sunken, raised, groove, ridge, 默认flat
        ##underline 	下划线, 默认没有; 取值就是带下划线的字符串索引,为 0 时,第一个字符带下划线
        ##justify:   "left", "center", "right"
        ##sticky=tk.E+tk.W ##水平方向延伸,垂直方向居中
        ##sticky=tk.E+tk.W ##水平方向延伸,垂直方向居中
        ##sticky=tk.N+tk.E+tk.W ##水平方向和垂直方向向下延伸
        ##sticky=tk.S+tk.E+tk.W ##水平方向和垂直方向向下延伸
        ###########cell.config(justify=tk.CENTER)
        # justify=CENTER 设置文本居中对齐
        # width=20, height=4 设置标签的宽和高  单位为字符个数
        # bd=2, relief=SOLID 设置边框的宽度  tk.SOLID   tk.GROOVR
        # wraplength=160 设置文字回卷宽度为160像素
        # anchor=W 设置内容在标签内部的左侧
        # font=('宋体', 18) 设置字体
        # 设置标签在窗口的顶端
        self.search_frame_height = 40
        self.header_height = 50
        self.footer_height = 40
        self.pages_frame_height = 30
        self.body_height = self.sheight - self.footer_height - self.pages_frame_height - self.search_frame_height
        ##print(f"body_height {self.body_height} line_height {self.body_height/35}")

        ######添加头部框架
        self.header_frame = tk.Frame(self.main_frame,width=self.swidth, height=self.header_height )
        self.header_frame.configure(bd=0)  ## bg="lightblue" ,highlightbackground="white",highlightcolor="white"  bg="lightblue",
        self.header_frame.pack(fill=tk.X,expand=False,padx=0,pady=0,ipadx=0,ipady=0,side=tk.TOP,anchor=tk.CENTER)
        #self.menu_frame.grid(row=0, column=0, columnspan=12, sticky=tk.EW, padx=2, pady=1)

        ######添加内容框架
        self.body_frame = tk.Frame(self.main_frame, width=self.swidth, height=self.body_height)
        self.body_frame.configure( bg="white",height=self.body_height,highlightbackground="#eeeeee",highlightcolor="#eeeeee")  ##,bd=5
        self.body_frame.pack(fill=tk.BOTH, expand=True, padx=0, pady=0,side=tk.TOP,anchor=tk.CENTER)
        #self.body_frame.grid(row=1, column=0, columnspan=12, sticky=tk.NSEW, padx=2,pady=1)  # tk.N + tk.S + tk.W + tk.E

        ######添加底部框架
        self.footer_frame = tk.Frame(self.main_frame, width=self.swidth, height=self.footer_height,background='white')
        #self.footer_frame.configure(background="#eeeeee", highlightbackground="#eeeeee",highlightcolor="#eeeeee")  ##,bd=5
        self.footer_frame.pack(fill=tk.X, expand=False, padx=0, pady=0, side=tk.TOP, anchor=tk.CENTER)
        # self.footer_frame.grid(row=2, column=0, columnspan=12, sticky=tk.EW, padx=2, pady=1)

        #####添加版本注释
        self.footer_label = tk.Label(self.footer_frame, text="Copyright © 2024 Lilin")
        self.footer_label.configure(justify=tk.CENTER, height=2, anchor=tk.CENTER, foreground="gray", background="#eeeeee",font=('宋体', 12))
        self.footer_label.pack(padx=0, pady=0, anchor=tk.CENTER, fill=tk.X, expand=True)  # ,fill=tk.BOTH    ###

        self.per_page = (self.body_height // 39 - 2)

        self.tooltip = tk.Label(self.body_frame, font=("Helvetica", 10), text='',foreground="black", background="white", borderwidth=1)
        self.tooltip.place(x=0, y=0, anchor='nw')
        ##print(f"初始化框架 init_frame body_height=={self.body_height} per_page=={self.per_page}")

        self.load_main_frame_tables()

    def run(self):
        self.root.mainloop()

###设置.py文件默认打开方式为Python解释器
def set_py_default_open_with_python():
    try:
        import winreg
        # 获取Python解释器的路径
        python_path = sys.executable
        sub_key1 = winreg.OpenKeyEx(winreg.HKEY_CLASSES_ROOT, '.py', 0, winreg.KEY_SET_VALUE)
        winreg.SetValueEx(sub_key1, '', 0, winreg.REG_SZ, f'Python.File')
        winreg.CloseKey(sub_key1)

        sub_key = winreg.OpenKeyEx(winreg.HKEY_CLASSES_ROOT, 'Python.File\Shell\open\command', 0, winreg.KEY_SET_VALUE)
        winreg.SetValueEx(sub_key, '', 0, winreg.REG_SZ, f'{python_path} "%1" %*')
        #winreg.SetValueEx(sub_key, '', 0, winreg.REG_SZ, f'{python_path} "%1"')
        winreg.CloseKey(sub_key)
        #print(f"set_py_default_open_with_python {python_path}")

    except Exception as e:
        messagebox.showinfo("info", f"set_py_default_open_with_python {e}")
        ##self.error(f"set_py_default_open_with_python {e}")

if __name__ == '__main__':
    # 配置数据库连接信息
    #print(f"os.name {os.name}")
    # if os.name == 'nt':
    #     set_py_default_open_with_python()

    ##my_app = Object(db_config)
    my_app = Object()
    my_app.run()


标签:name,python,self,label,V1,tk,frame,table,资源管理
From: https://www.cnblogs.com/rooker11/p/18641515

相关文章

  • Python项目目录树生成
    1、生成项目目录树在当前文件所在文件夹下运行。2、代码dir_tree.py#-*-coding:utf-8-*-importsysfrompathlibimportPathclassDirectionTree(object):"""生成目录树@pathname:目标目录@filename:要保存成文件的名称"""def__i......
  • 在Python中加载OneNote文档的指南
    #在Python中加载OneNote文档的指南老铁们,今天咱们来聊聊如何在你的Python应用中从OneNote加载文档。这波操作可以说是相当丝滑,尤其是当你想整合微软的服务到你的应用里。对于需要处理OneNote数据的开发者来说,掌握这项技术绝对是个加分项。##技术背景介绍在当今互联......
  • 保姆级Python安装教程、Pycharm安装教程,附转中文版教程,零基础小白包看包会!
    今天刚好换了新的电脑,需要重新安装一下pyhton和PyCharm,就简单写一个PyCharm安装教程吧。当然Python安装和Pycharm安装包以及资料合集已准备好→点击文字领取一、PyCharm下载1、进入官网:官网地址:https://www.jetbrains.com/2、点击【DeveloperTools】开发者工具,选择......
  • 使用Python爬取BOSS直聘职位数据并保存到Excel
    使用Python爬取BOSS直聘职位数据并保存到Excel在数据分析和挖掘中,爬取招聘网站数据是一项常见的任务。本文将详细介绍如何使用Python爬取BOSS直聘上与“测试工程师”相关的职位数据,并将其保存到Excel文件中。通过逐步分解代码和添加详细注释,我们将深入了解整个实现过程。......
  • 推荐一款Python开源自动化脚本工具:AutoKey
    1、前言在数字化时代,自动化工具成为了提升工作效率和生产力的重要手段。Python作为一种广泛使用的编程语言,以其强大的功能和易用性受到许多开发者的青睐。而今天给大家推荐一款开源的自动化脚本工具:AutoKey。结合Python的强大编程能力与AutoKey的任务自动化特性,用户可以高效地......
  • Python how to use dmPython
     importdmPythondefconnect_dm_database():#数据库连接参数password='xxxxxxxxxx'#数据库密码server='127.0.0.1'#数据库服务器IPport=5236#数据库端口号,默认为5236try:#连接到达梦数据库con......
  • 基于python大数据的图书销售系统
    标题:基于Python大数据的图书销售系统研究内容:1.摘要摘要:随着信息技术的不断发展,大数据在各个领域的应用越来越广泛。本文旨在研究基于Python大数据的图书销售系统,通过对大量的图书销售数据进行分析和挖掘,为图书销售企业提供决策支持。本文首先介绍了研究的背景和目的,然......
  • 【Python应用】如何将log日志生成html形式的报告
    本文介绍了特殊格式log日志生成自定义报告方法,项目地址https://gitee.com/JasonZhu2021/reporter-tool-python前言如果在日常工作中,遇到一堆数据,但是想实现自动化将数据生成报告或者统计报表,这时候就需要掌握一些定制化输出报告的技能了;模板文件:对于特定格式的报告输出,首先......
  • python将列表拆分为指定的组
    defchunk_list_by_groups(lst,groups):"""将列表lst拆分成包含指定组数的子列表"""#计算每组应该有多少个元素n=len(lst)//groups#计算剩余的元素个数remainder=len(lst)%groups#初始化结果列表result=[]#初始化起始索引......
  • 利用Python爬虫获取亚马逊商品评论的详细指南
    引言在电子商务领域,用户评论是了解产品口碑和市场反馈的重要渠道。亚马逊作为全球领先的电商平台,拥有海量的商品评论数据。本文将介绍如何使用Python编写爬虫程序,从亚马逊网站获取商品评论数据,并提供详细的代码示例。准备工作在开始编写爬虫之前,我们需要做一些准备工作:安......