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