python 资源管理工具V1

news/2025/2/28 15:22:18/文章来源:https://www.cnblogs.com/rooker11/p/18641515

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 filedialogtry:import configparser
except:os.popen('python -m pip install configparser==5.3.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/ ')
finally:import configparsertry:import pymysql
except:os.popen('python -m pip install pymysql==0.9.3 -i https://pypi.tuna.tsinghua.edu.cn/simple/ ')
finally:import pymysqltry: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 = Falseself.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() - 10self.sheight = self.root.winfo_screenheight() - 75self.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 = Trueself.auth_username = usernamereturn Trueelse:self.auth_username = ""self.auth_status = Falsereturn Falseexcept pymysql.Error as e:return Falsedef 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 = Falsefor 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 = Truebreakif self.auth_status is True and table_auth is True:return Trueelse:#messagebox.showinfo("Error", "用户权限不足,请先登陆或添加权限!")return Falseexcept pymysql.Error as e:#messagebox.showinfo("Error", "用户权限不足,请先登陆或添加权限!")return Falsedef 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 = Truemsg = f"Database {database_name} created successfully."#print(msg)cursor.close()self.conn.close()except Exception as e:status = Falsemsg = f"The error '{e}' occurred."return status, msgdef check_db_conn(self):try:database = self.db_config['database']self.conn, msg = self.db_connect()#conn.cursor()self.conn.close()status = Trueexcept Exception as e:try:self.db_config['database'] = 'mysql'status, msg = self.create_database_if_not_exists(database)self.db_config['database'] = databaseif status:self.conn, msg = self.db_connect()self.conn.close()status = Trueelse:self.error(msg)status = Falsemsg = 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,msgdef 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_configconfig['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 = Nonemsg = f"database {database} connect error ::" + str(e)return conn,msgdef 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_listexcept Exception as e:#print(f"check_tables ::{str(e)}")return Falsedef 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 Trueelse:return Falseexcept pymysql.Error as e:messagebox.showinfo("error",f"{e}")#print(f"check_tables ::{str(e)}")return Falsedef 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 Trueexcept pymysql.Error as e:messagebox.showinfo("error",f"{e}")return Falsedef 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 Trueexcept Exception as e:self.error(f"""exec sql "{sql}" error! ,{e}""")return Falsedef 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_pageoffset = (page - 1) * per_pagesql = 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 ) + 1else:self.totals_pages = Nonecursor.execute(f"{sql}")results = cursor.fetchall()cursor.close()self.conn.close()return resultsexcept 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_dictexcept pymysql.Error as e:messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")return Nonedef get_tables_fields_str(self,table_name):try:field_list = list(self.get_tables_fields(table_name).keys())[1:]fields = ','.join(field_list)return fieldsexcept pymysql.Error as e:messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")return Nonedef 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 Noneexcept pymysql.Error as e:messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")return Nonedef 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 Noneexcept pymysql.Error as e:messagebox.showerror("错误", f"获取model描述时出错: {e}")return Nonedef 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+1if 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 = Falseif results is False:return False,msgelse: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 + 1if 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 = Falseelse:msg = "ok"results = Trueif results:msg = "ok"return results,msgexcept Exception as e:msg = f"更新表结构或数据是报错:{e}"return False,msgdef 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 csvwith 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_nameelse: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}是报错,请检查文件字段名是否和要导入的模块字段名一致!"breakelse: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 csvfields = 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,datetimefiletypes = (('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) -1table_col_num=len(field_list)+1row_header_width = 60row_control_width1 = 150if table_name == 'o_modules':row_btn_width1 = 145row_body_width = self.swidth - row_header_width - row_control_width1 - row_btn_width1table_field_width = int(row_body_width / field_num)row_control_width = (row_body_width % field_num) + row_control_width1else:row_body_width = self.swidth - row_header_width - row_control_width1table_field_width = int(row_body_width / field_num)row_control_width = (row_body_width % field_num) + row_control_width1table_label_width = int(table_field_width / 8)label_header_width = 8label_control_width1 = int(row_control_width / 8 / field_num)label_control_width = 12str_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_valueelif 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 + 1table_col_num = len(field_list)+2else:c_num = f_colif 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_widtht_label_header_1.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12), background='#A593CE')  ##wraplength=160t_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=1t_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_widtht_label_header_2.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER,font=('宋体', 12), background='#A593CE')  ##wraplength=160t_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 - 2else:table_label_width11 = table_label_width - 3elif field_num in [7,8]:if f_col == 5:table_label_width11 = table_label_width - 1else:table_label_width11 = table_label_width - 2else:if f_col > 5:table_label_width11 = table_label_width - 1else:table_label_width11 = table_label_widthelse: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_widtht_label_header.config(justify=tk.CENTER, height=2, bd=0, relief=tk.RIDGE, anchor=tk.CENTER, font=('宋体', 12), background='#A593CE')  ##wraplength=160t_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_widtht_label_input.configure(bd=2, relief=tk.GROOVE,font=('宋体', 12 ))  # background="#eeeeee"  ,borderwidth=1,border=1t_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 + 3if self.totals_pages is not None:t_label_num = (self.page-1) * self.per_page + row_num-2else:t_label_num = row_num - 2if row % 2 == 0:row_color='#E7D3B4'else:row_color='#eeeeee'for col, value in enumerate(rowData):if table_name == 'o_modules':col_num = col+1table_col_num = len(field_list) + 2else:col_num = colif 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_widthtable_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=160button_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 - 2else:table_label_width11 = table_label_width - 3elif field_num in [7, 8]:if col == 5:table_label_width11 = table_label_width - 1else:table_label_width11 = table_label_width - 2else:if col > 5:table_label_width11 = table_label_width - 1else:table_label_width11 = table_label_widthelse: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_widthif 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 + 1t_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 eeeeeet_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()  ###删除treeviewexcept Exception as e:passfinally:##pages_frame.pack_forget()#####添加分页框架self.pages_frame = pages_frametry:self.table_frame.destroy()  ###删除treeviewexcept Exception as e:passfinally:##table_frame.pack_forget()######创建内容表单,添加表单控件self.table_frame = table_frameexcept pymysql.Error as e:messagebox.showerror("错误", f"加载子菜单数据表格时出错: {e}")def set_page(self, event):event_type = event.typeobj = event.widgetif event_type == "4":#print(f"obj.cget {obj.cget('text')} id {obj.cget('repeatinterval')} event.type {event.type} Double-Button-1 ")  # event.typeif 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.typeobj = event.widgetif event_type == "4":####鼠标单击左键事件# print(f"obj.cget {obj.cget('text')} id {obj.cget('repeatinterval')} event.type {event.type} Double-Button-1 ")  # event.typeif obj.__class__.__name__ == 'Label':objtext = obj.cget('text')if objtext.startswith('http://') or objtext.startswith('https://'):pyperclip.copy(objtext)import webbrowserwebbrowser.open(objtext)def mouse_over_event(self,event):#background = '#98D2F5'#background = row_colorevent_type = event.typeobj =  event.widget##print(f" obj.__class__.__name__  {obj.__class__.__name__ }   event.type {event.type} ")  # event.typeif event_type == '6':####鼠标光标进入组件事件#print(f"obj.cget {obj.cget('text')}  event.type {event.type} Enter")  # event.typeif obj.__class__.__name__ == 'Label':if self.tipwindow:# 更新提示窗口的位置,使其跟随鼠标x = event.x_root + 20y = 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.typeif obj.__class__.__name__ == 'Label':obj.configure(background="#98D2F5")objtext = obj.cget('text')if len(objtext) > 0:x = obj.winfo_rootx() + obj.winfo_width() // 2y = 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  Returnif 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.typeif 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  Returnif 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=160self.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=160self.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=160self.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=160self.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=160self.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'))  # cbdde8self.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=0self.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.RIDGEself.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()  ###删除treeviewexcept Exception as e:passfinally:self.menu_frame = menu_frametry:self.search_frame.destroy()  ###删除treeviewexcept Exception as e:passfinally:self.search_frame = search_frametry:self.sep_bef.destroy()  ###删除treeviewexcept Exception as e:passfinally:self.sep_bef = sep_beftry:self.sep_aft.destroy()  ###删除treeviewexcept Exception as e:passfinally:self.sep_aft = sep_aftexcept 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 = 1else:self.page = pageself.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=5init_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=160self.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=160self.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=160self.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=160self.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=160self.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=160self.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=160self.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_framedef 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 = 40self.header_height = 50self.footer_height = 40self.pages_frame_height = 30self.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=5self.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=5self.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.executablesub_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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/861438.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于时间轴的项目进度管理工具

在项目管理中,时间轴是一种强大的工具,它能够直观地展示项目的进度、任务的先后顺序以及时间的推移。通过时间轴,项目团队可以清晰地把握项目的整体节奏,及时发现潜在问题,做出合理的决策。市面上基于时间轴的项目进度管理工具众多,每一款都有其独特的特点和优势。本文将…

(数据科学学习手札164)在vscode中调用Deepseek进行AI辅助编程

本文示例配置文件已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes1 简介大家好我是费老师,最近国产大模型Deepseek v3新版本凭借其优秀的模型推理能力,讨论度非常之高🔥,且其官网提供的相关大模型API接口服务价格一直走的“价格屠夫”路线,性…

【4】0x10服务27服务

1. 0x10服务之诊断会话控制 诊断仪与ECU之间的诊断通信过程就相当于两个人的会话过程,你一言,我一语,会话可以在不同的场景下进行。 0x10服务即诊断会话控制,规定了默认会话(01)、拓展会话(03)、编程会话(02),三种常见的诊断会话。 默认会话:22、14、19、11服务等。…

阳大壮AI助手

你还在为选择哪个AI产品而苦恼吗?试试哥们这个阳大壮http://47.95.159.19:9090/

防护用具穿戴智能识别摄像机

防护用具穿戴智能识别摄像机通过智能技术监测和识别工人是否佩戴了防护用具。这种摄像机可以准确识别工人的身体区域,并通过智能算法检测身体区域是否佩戴了必要的防护用具,实现自动识别和记录。一旦有工人未佩戴防护用具,监测智能识别摄像机会立即发出警报,提醒相关人员及…

springboot~多节点应用里的雪花算法唯一性

雪花算法的唯一性,在单个节点中是可以保证的,对应kubernetes中的应用,如果是横向扩展后,进行多副本的情况下,可能出现重复的ID,这需要我们按着pod_name进行一个workId的生成,我还是建议通过不引入第三方组件和网络请求的前提下解决这个问题,所以我修改了kubernetes的ya…

怎么编写库卡KUKA机器人专业程序,高级写法案例

KUKA程序写法案例分享换抢盘抓抓手程序:DEF Q1_PICKGRPPER( ) :程序名称INI :系统初始化 PTP HOME Vel= 100 % DEFAULT :HOME 原点OUT 272 Grip2_Bracket_Open State=TRUE :输出272抓手2防尘盖打开信号为真OUT 271 Grip2_Bra…

佩戴安全头盔监测识别摄像机

佩戴安全头盔监测识别摄像机作为一种先进的监控设备,对于提高工作场所的安全水平和管理效率具有重要意义。然而,在使用过程中,我们也需要注意保护员工的隐私和个人信息安全,加强数据的保护和管理,在促进工作场所安全的同时,也保障员工的合法权益。同时,也需要结合国家相…

收获满满:2024软工已通关

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/SE2024这个作业要求在哪里 https://edu.cnblogs.com/campus/fzu/SE2024/homework/13315这个作业的目标 回顾课程学习情况并总结收获学号 102202114一、学期回顾 初闻软件工程 第一次听说软件工程,就知道这是一门不好…

客流量监测识别摄像机

客流量监测识别摄像机作为一种新型的监测设备,可以广泛应用于商场、车站、机场、展览馆等各类公共场所,帮助管理者有效管理客流量和优化服务质量。总之,客流量监测识别摄像机是一种有益的监控设备,为公共场所的管理和安全提供了有力支持。在使用时需谨慎操作,维护监控数据…

Danfoss FC51变频器参数设置

LCP 4个功能组:数字式显示器 菜单键 导航键 操作键和指示灯(绿:变频器打开黄:警告红:报警)点按[Menu]键可选择一下菜单:状态菜单:读数模式和手动启动模式下均可访问状态菜单。读数模式下屏幕将显示当前所选读数参数的值 快捷菜单:Quick Menu快速设置常用参数 主菜单:…

基于看板的项目管理工具

在项目管理领域,看板作为一种高效的可视化工具,正日益受到众多团队的青睐。它通过直观的展示方式,帮助团队成员清晰地了解项目的进展、任务分配以及工作流程。市面上基于看板的项目管理工具种类繁多,每一款都有其独特的特点和优势。本文将为大家介绍多款基于看板的项目管理…