VWED_server/packaging/config_tool/integrated_config_gui.py
2025-09-09 10:41:27 +08:00

268 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
集成的配置GUI界面
配置完成后直接启动服务
"""
import os
import sys
import tkinter as tk
from tkinter import ttk, messagebox
import configparser
import threading
from pathlib import Path
class IntegratedConfigGUI:
"""集成配置GUI界面"""
def __init__(self, on_completed_callback):
self.on_completed_callback = on_completed_callback
self.config_file = "config.ini"
self.config_data = {}
self.root = None
self.load_config()
def load_config(self):
"""加载配置"""
if os.path.exists(self.config_file):
config = configparser.ConfigParser()
config.read(self.config_file, encoding='utf-8')
# 转换为字典格式
for section in config.sections():
self.config_data[section] = dict(config[section])
else:
# 默认配置
self.config_data = {
'database': {
'username': 'root',
'password': 'root',
'host': 'localhost'
},
'api': {
'tf_api_base_url': 'http://111.231.146.230:4080/jeecg-boot'
}
}
def save_config(self):
"""保存配置"""
config = configparser.ConfigParser()
# 添加配置节
for section_name, section_data in self.config_data.items():
config.add_section(section_name)
for key, value in section_data.items():
config.set(section_name, key, str(value))
with open(self.config_file, 'w', encoding='utf-8') as f:
config.write(f)
def setup_gui(self):
"""设置GUI界面"""
self.root = tk.Tk()
self.root.title("VWED任务系统 - 配置与启动")
self.root.geometry("700x550")
self.root.resizable(True, True)
# 设置窗口居中
self.root.geometry("+%d+%d" % ((self.root.winfo_screenwidth()/2 - 350),
(self.root.winfo_screenheight()/2 - 275)))
# 创建主框架
main_frame = ttk.Frame(self.root, padding="20")
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
# 配置行列权重
self.root.columnconfigure(0, weight=1)
self.root.rowconfigure(0, weight=1)
main_frame.columnconfigure(1, weight=1)
# 标题
title_label = ttk.Label(main_frame, text="VWED任务系统配置", font=("Arial", 18, "bold"))
title_label.grid(row=0, column=0, columnspan=3, pady=(0, 30))
# 说明文字
desc_label = ttk.Label(main_frame, text="请配置数据库连接和API地址配置完成后将自动启动服务",
font=("Arial", 10))
desc_label.grid(row=1, column=0, columnspan=3, pady=(0, 20))
# 数据库配置区域
db_frame = ttk.LabelFrame(main_frame, text="数据库配置", padding="15")
db_frame.grid(row=2, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 15))
db_frame.columnconfigure(1, weight=1)
# 数据库用户名
ttk.Label(db_frame, text="用户名:").grid(row=0, column=0, sticky=tk.W, padx=(0, 15), pady=5)
self.db_username = tk.StringVar(value=self.config_data.get('database', {}).get('username', 'root'))
db_user_entry = ttk.Entry(db_frame, textvariable=self.db_username, width=50)
db_user_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), pady=5)
# 数据库密码
ttk.Label(db_frame, text="密码:").grid(row=1, column=0, sticky=tk.W, padx=(0, 15), pady=5)
self.db_password = tk.StringVar(value=self.config_data.get('database', {}).get('password', 'root'))
db_pass_entry = ttk.Entry(db_frame, textvariable=self.db_password, show="*", width=50)
db_pass_entry.grid(row=1, column=1, sticky=(tk.W, tk.E), pady=5)
# 数据库主机
ttk.Label(db_frame, text="主机地址:").grid(row=2, column=0, sticky=tk.W, padx=(0, 15), pady=5)
self.db_host = tk.StringVar(value=self.config_data.get('database', {}).get('host', 'localhost'))
db_host_entry = ttk.Entry(db_frame, textvariable=self.db_host, width=50)
db_host_entry.grid(row=2, column=1, sticky=(tk.W, tk.E), pady=5)
# API配置区域
api_frame = ttk.LabelFrame(main_frame, text="API配置", padding="15")
api_frame.grid(row=3, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 15))
api_frame.columnconfigure(1, weight=1)
# TF API基础URL
ttk.Label(api_frame, text="TF API地址:").grid(row=0, column=0, sticky=tk.W, padx=(0, 15), pady=5)
self.tf_api_url = tk.StringVar(value=self.config_data.get('api', {}).get('tf_api_base_url', 'http://111.231.146.230:4080/jeecg-boot'))
api_entry = ttk.Entry(api_frame, textvariable=self.tf_api_url, width=50)
api_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), pady=5)
# 按钮区域
button_frame = ttk.Frame(main_frame)
button_frame.grid(row=4, column=0, columnspan=3, pady=(25, 15))
# 测试连接按钮
test_btn = ttk.Button(button_frame, text="测试数据库连接", command=self.test_database_connection)
test_btn.pack(side=tk.LEFT, padx=(0, 15))
# 完成配置并启动服务按钮
start_btn = ttk.Button(button_frame, text="完成配置并启动服务", command=self.complete_and_start,
style="Accent.TButton")
start_btn.pack(side=tk.LEFT, padx=(0, 15))
# 仅保存配置按钮
save_btn = ttk.Button(button_frame, text="仅保存配置", command=self.save_configuration)
save_btn.pack(side=tk.LEFT)
# 状态区域
status_frame = ttk.LabelFrame(main_frame, text="状态信息", padding="10")
status_frame.grid(row=5, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
status_frame.columnconfigure(0, weight=1)
status_frame.rowconfigure(0, weight=1)
# 状态文本
self.status_text = tk.Text(status_frame, height=8, width=80, wrap=tk.WORD)
status_scrollbar = ttk.Scrollbar(status_frame, orient=tk.VERTICAL, command=self.status_text.yview)
self.status_text.configure(yscrollcommand=status_scrollbar.set)
self.status_text.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
status_scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
# 配置主框架的行权重
main_frame.rowconfigure(5, weight=1)
self.log_message("欢迎使用VWED任务系统配置工具")
self.log_message("请检查并修改配置参数,然后点击\"完成配置并启动服务\"")
# 设置关闭窗口处理
self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
def log_message(self, message: str):
"""记录日志消息"""
self.status_text.insert(tk.END, f"{message}\n")
self.status_text.see(tk.END)
self.root.update()
def test_database_connection(self):
"""测试数据库连接"""
try:
import pymysql
self.log_message("正在测试数据库连接...")
connection = pymysql.connect(
host=self.db_host.get(),
user=self.db_username.get(),
password=self.db_password.get(),
charset='utf8mb4'
)
with connection.cursor() as cursor:
cursor.execute("SELECT VERSION()")
version = cursor.fetchone()
connection.close()
self.log_message(f"✓ 数据库连接成功! MySQL版本: {version[0]}")
messagebox.showinfo("成功", "数据库连接测试成功!")
except Exception as e:
error_msg = f"✗ 数据库连接失败: {str(e)}"
self.log_message(error_msg)
messagebox.showerror("错误", error_msg)
def save_configuration(self):
"""保存配置"""
try:
# 更新配置数据
self.config_data['database'] = {
'username': self.db_username.get(),
'password': self.db_password.get(),
'host': self.db_host.get()
}
self.config_data['api'] = {
'tf_api_base_url': self.tf_api_url.get()
}
# 保存到文件
self.save_config()
self.log_message("✓ 配置已保存")
messagebox.showinfo("成功", "配置已保存成功!")
except Exception as e:
error_msg = f"✗ 保存配置失败: {str(e)}"
self.log_message(error_msg)
messagebox.showerror("错误", error_msg)
def complete_and_start(self):
"""完成配置并启动服务"""
try:
# 先保存配置
self.save_configuration()
self.log_message("配置已保存,正在启动服务...")
# 立即关闭窗口
self.close_window()
# 调用完成回调
if self.on_completed_callback:
self.on_completed_callback(self.config_data)
except Exception as e:
error_msg = f"✗ 启动服务失败: {str(e)}"
self.log_message(error_msg)
messagebox.showerror("错误", error_msg)
def close_window(self):
"""关闭窗口"""
if self.root:
self.root.quit()
self.root.destroy()
def on_closing(self):
"""处理窗口关闭事件"""
if messagebox.askokcancel("退出", "确定要退出配置工具吗?\n退出后将无法启动服务。"):
self.close_window()
sys.exit(0)
def run(self):
"""运行GUI"""
self.setup_gui()
self.root.mainloop()
def main():
"""测试主函数"""
def on_completed(config_data):
print("配置完成:", config_data)
app = IntegratedConfigGUI(on_completed)
app.run()
if __name__ == "__main__":
main()