实现树状编辑

This commit is contained in:
Voge1imkafig 2025-08-07 18:16:09 +08:00
parent 832c91454e
commit f8f7ad1e8e
7 changed files with 705 additions and 40 deletions

1
.gitignore vendored
View File

@ -204,3 +204,4 @@ __marimo__/
测试数据/
model/
output/

View File

@ -1,12 +1,12 @@
from PySide6.QtWidgets import (QMainWindow, QWidget, QGridLayout,
from PySide6.QtWidgets import (QMainWindow, QWidget, QGridLayout, QMessageBox,
QPushButton, QSizePolicy, QSplitter, QToolBar)
from PySide6.QtGui import QFontDatabase
from PySide6.QtCore import Signal, Qt
import os
from info_core.defines import *
from info_core.MyQtClass import ConfigComboBoxGroup, FolderDropWidget
from info_core.MyQtClass import (ConfigComboBoxGroup, FolderDropWidget,
OutputDirSelector, FolderBrowser)
class ReportGeneratorUI(QMainWindow):
send_baogao_choose_info = Signal(list[str])
@ -49,8 +49,6 @@ class ReportGeneratorUI(QMainWindow):
self.staff_group = ConfigComboBoxGroup("单次检查配置信息", is_project=False)
# 第二行:导入图片路径、填写机组信息
self.picture_group = FolderDropWidget()
# self.image_analysis =
# self.main_layout.addWidget(self.image_analysis, 1, 1)
# 第三行:生成报告按钮(跨两列)
self.fill_turbine_info_button()
self.fill_btn.clicked.connect(self.on_fill_clicked)
@ -79,15 +77,29 @@ class ReportGeneratorUI(QMainWindow):
# 设置分割器初始比例
self.splitter.setStretchFactor(0, 1)
self.splitter.setStretchFactor(1, 4)
self.init_toolbar()
self.create_warning_box()
self.create_info_fill_widget()
def init_toolbar(self):
self.toolbar = QToolBar()
self.addToolBar(self.toolbar)
self.toolbar.setMovable(False)
self.toolbar.setFloatable(False)
new_action = self.toolbar.addAction("重置布局比例")
self.output_dir_selector = OutputDirSelector()
if not os.path.exists(os.getcwd() + "/output"):
os.mkdir(os.getcwd() + "/output")
self.output_dir_selector.set_output_dir(os.getcwd() + "/output")
output_dir_choose_action = self.toolbar.addAction("选择输出目录")
self.toolbar.addSeparator()
new_action.triggered.connect(self.reset_splitter)
output_dir_choose_action.triggered.connect(self.choose_output_dir)
def reset_splitter(self):
"""重置分割器的比例"""
total_size = sum(self.splitter.sizes()) # 获取当前总大小
@ -96,12 +108,38 @@ class ReportGeneratorUI(QMainWindow):
int(total_size * 0.8) # 第二部分占 80%
])
def choose_output_dir(self):
"""选择输出目录"""
self.output_dir_selector.show()
def create_info_fill_widget(self):
self.info_fill_widget = FolderBrowser()
def create_warning_box(self):
self.warning_box = QMessageBox(self)
self.warning_box.setWindowTitle("警告")
self.warning_box.setIcon(QMessageBox.Warning)
self.warning_box.setStyleSheet(WARNING_MESSAGE_BOX_STYLE + MESSAGE_BOX_BUTTON_STYLE)
def on_fill_clicked(self):
"""填写信息"""
# 读取各个配置信息
turbine_file_list = self.picture_group.get_selected_folders()
print(turbine_file_list)
if len(self.picture_group.get_selected_folders()) <= 0:
self.warning_box.setText("请先选择机组目录")
self.warning_box.exec()
return
if self.project_group.get_current_config_file() is None:
self.warning_box.setText("请先选择/添加项目配置信息")
self.warning_box.exec()
return
if self.staff_group.get_current_config_file() is None:
self.warning_box.setText("请先选择/添加人员配置信息")
self.warning_box.exec()
return
self.info_fill_widget.set_output_path(self.get_output_path())
self.info_fill_widget.set_initial_folders(self.get_choosen_files())
self.info_fill_widget.show()
# search_file_list = []
# if self.image_analysis.check_is_waibu:
# search_file_list.append("外汇总")
@ -111,6 +149,12 @@ class ReportGeneratorUI(QMainWindow):
# search_file_list.append("防汇总")
# self.send_baogao_choose_info.emit(search_file_list)
def get_choosen_files(self):
return self.picture_group.get_selected_folders()
def get_output_path(self):
return self.output_dir_selector.get_output_dir()
def create_button(self, text):
"""创建统一风格的按钮"""
btn = QPushButton(text)

View File

@ -1,15 +0,0 @@
{
"检查人员": "213",
"厂家人员": "213",
"业主人员": "213",
"数据处理人员": "213",
"报告编制人员": "123",
"机组型号": "123",
"机组厂家": "213",
"施工日期": "开始-结束",
"": "123",
"外部检查": true,
"内部检查": true,
"防雷检查": true,
"json路径": "/home/dtyx/桌面/yhh/ReportGenerator/config/单次检查配置信息"
}

View File

@ -0,0 +1,16 @@
{
"检查人员": "张三",
"厂家人员": "李四",
"业主人员": "王五",
"数据处理人员": "六麻子",
"报告编制人员": "赵六",
"机组型号": "model1",
"机组厂家": "某厂",
"叶片型号": "model--1",
"叶片厂家": "某场",
"施工日期": "2025/4/3-2025/4/30",
"外部检查": true,
"内部检查": true,
"防雷检查": true,
"json路径": "/home/dtyx/桌面/yhh/ReportGenerator/config/单次检查配置信息"
}

View File

@ -1,14 +1,14 @@
{
"项目名称": "123",
"风场名": "123",
"风场地址": "123",
"甲方公司": "123",
"甲方负责人": "123",
"甲方负责人电话": "123",
"项目名称": "某集团某场外部内部防雷检测项目",
"风场名": "某风场",
"风场地址": "某地",
"甲方公司": "",
"甲方负责人": "甲负责人",
"甲方负责人电话": "181xxxxxxxxx",
"乙方公司": "武汉迪特聚能科技有限公司",
"乙方负责人": "123",
"乙方负责人电话": "123",
"项目规格": "123",
"项目工期": "123",
"乙方负责人": "乙负责人",
"乙方负责人电话": "181xxxxxxxx",
"项目规格": "20台",
"项目工期": "30天",
"json路径": "/home/dtyx/桌面/yhh/ReportGenerator/config/项目基本信息"
}

View File

@ -3,11 +3,13 @@ from PySide6.QtWidgets import (QGroupBox, QVBoxLayout, QHBoxLayout, QCheckBox,
QFileDialog, QMessageBox, QLabel, QWidget,
QTextBrowser, QApplication, QCompleter, QFrame,
QListWidgetItem, QListWidget, QAbstractItemView,
QStackedWidget, QStackedLayout)
QStackedWidget, QStackedLayout, QStyledItemDelegate,
QTreeView, QSplitter, QFileSystemModel)
from PySide6.QtCore import (QDateTime,QTimer,QDateTime,Signal,QSettings,
QSortFilterProxyModel, QSize)
QSortFilterProxyModel, QSize, QDir)
from PySide6.QtGui import (QPixmap, QDragEnterEvent, QDropEvent, Qt, QIcon,
QFontMetrics)
QFontMetrics, QStandardItem, QStandardItemModel,
QAction)
import json, sys, os
from info_core.defines import *
@ -144,7 +146,8 @@ class ConfigComboBoxGroup(QGroupBox):
QMessageBox.warning(self, '警告', '没有选中任何项目。')
def get_current_config_file(self):
"""获取当前选中的配置文件"""
return os.path.join(self.config_dir, self.combo_box.currentText() + ".json")
if self.combo_box.currentText():
return os.path.join(self.config_dir, self.combo_box.currentText() + ".json")
class AddProjectDialog(QDialog):
@ -1047,4 +1050,537 @@ class DraggableLine(QFrame):
def mouseReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
self.dragging = False
self.dragging = False
class OutputDirSelector(QWidget):
# 定义一个信号,当路径改变时发出
path_changed = Signal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.output_dir = ""
self.init_ui()
self.set_style()
def init_ui(self):
# 主布局
layout = QVBoxLayout(self)
layout.setSpacing(10)
layout.setContentsMargins(0, 0, 0, 0)
# 组框
self.group_box = QFrame()
self.group_box.setFrameShape(QFrame.StyledPanel)
group_layout = QVBoxLayout(self.group_box)
group_layout.setSpacing(GROUP_BOX_SPACING)
group_layout.setContentsMargins(*GROUP_BOX_MARGINS)
# 标题标签
self.setWindowTitle("选择输出目录")
# 路径显示标签
self.path_label = QLabel("未选择文件夹")
self.path_label.setWordWrap(True)
self.path_label.setAlignment(Qt.AlignLeft | Qt.AlignTop)
# 选择按钮
self.select_button = QPushButton("选择输出文件夹")
self.select_button.clicked.connect(self.select_output_dir)
# 添加部件到布局
group_layout.addWidget(self.path_label)
group_layout.addWidget(self.select_button)
# 添加组框到主布局
layout.addWidget(self.group_box)
def set_style(self):
# 设置组框样式
self.group_box.setStyleSheet(GROUP_BOX_STYLE)
# 设置路径显示样式
self.path_label.setStyleSheet(PATH_DISPLAY_STYLE)
# 设置按钮样式
self.select_button.setStyleSheet(PRIMARY_BUTTON_STYLE)
# 设置最小尺寸
self.group_box.setMinimumSize(GROUP_BOX_MIN_WIDTH, GROUP_BOX_MIN_HEIGHT)
def select_output_dir(self):
"""打开文件夹选择对话框"""
dir_path = QFileDialog.getExistingDirectory(
self,
"选择输出文件夹",
"", # 默认路径为空,使用系统默认
QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks
)
if dir_path: # 如果用户选择了文件夹
self.output_dir = dir_path
self.path_label.setText(dir_path)
self.path_changed.emit(dir_path) # 发出路径改变信号
def get_output_dir(self):
"""获取输出路径"""
return self.output_dir
def set_output_dir(self, path):
"""设置输出路径"""
if path:
self.output_dir = path
self.path_label.setText(path)
self.path_changed.emit(path)
class JsonFileHandler:
"""处理JSON文件的读写操作"""
@staticmethod
def read_json(file_path):
"""读取JSON文件"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception as e:
print(f"Error reading JSON file {file_path}: {e}")
return None
@staticmethod
def write_json(file_path, data):
try:
# 检查目录是否可写
dir_path = os.path.dirname(file_path)
if not os.access(dir_path, os.W_OK):
print(f"错误:目录不可写 {dir_path}")
return False
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
print(f"成功写入文件:{file_path}")
return True
except Exception as e:
print(f"写入文件错误:{str(e)}")
return False
class TreeModelManager:
"""管理树形模型的数据操作"""
@staticmethod
def create_left_tree_model(folder_list):
"""创建左侧文件夹树模型"""
model = QStandardItemModel()
model.setHorizontalHeaderLabels(["Folder Structure"])
folder_map = {}
for folder_path in folder_list:
folder_name = os.path.basename(folder_path)
folder_map[folder_name] = folder_path
parent_item = QStandardItem(folder_name)
model.appendRow(parent_item)
try:
for child in os.listdir(folder_path):
child_path = os.path.join(folder_path, child)
if os.path.isdir(child_path):
child_item = QStandardItem(child)
parent_item.appendRow(child_item)
except Exception as e:
print(f"Error reading folder {folder_path}: {e}")
return model, folder_map
@staticmethod
def create_right_tree_model(folder_names):
"""创建右侧可编辑树模型"""
model = QStandardItemModel()
model.setHorizontalHeaderLabels(["Name", "Value"])
json_data = {}
for folder_name in folder_names:
parent_item = QStandardItem(folder_name)
parent_item.setEditable(False)
# 添加机组编号
turbine_item = QStandardItem("turbinecode")
turbine_value = QStandardItem(folder_name.replace("机组", "").strip())
turbine_value.setEditable(True)
parent_item.appendRow([turbine_item, turbine_value])
# 添加默认的三个子部件
for i in range(1, 4):
part_item = QStandardItem(f"part{i}")
part_item.setEditable(False)
code_item = QStandardItem("001")
code_item.setEditable(True)
part_item.appendRow([QStandardItem("code"), code_item])
parent_item.appendRow(part_item)
model.appendRow(parent_item)
# 初始化JSON数据
json_data[folder_name] = {
"turbinecode": folder_name.replace("机组", "").strip(),
"part1": {"code": "001"},
"part2": {"code": "001"},
"part3": {"code": "001"}
}
return model, json_data
@staticmethod
def update_model_from_json(model, folder_name, json_data):
"""根据JSON数据更新模型"""
parent_item = None
for i in range(model.rowCount()):
item = model.item(i)
if item and item.text() == folder_name:
parent_item = item
break
if parent_item and folder_name in json_data:
data = json_data[folder_name]
# 更新机组编号
turbine_item = parent_item.child(0)
if turbine_item and turbine_item.child(0, 1):
turbine_item.child(0, 1).setText(data.get("turbinecode", ""))
# 更新部件信息
for j in range(1, 4):
part_item = parent_item.child(j)
if part_item:
part_name = part_item.text()
if part_name in data:
code_item = part_item.child(0, 1)
if code_item:
code_item.setText(data[part_name].get("code", "001"))
@staticmethod
def update_json_from_model(model, json_data):
for i in range(model.rowCount()):
folder_index = model.index(i, 0)
folder_name = model.data(folder_index)
if not folder_name:
continue
# 确保数据结构存在
if folder_name not in json_data:
json_data[folder_name] = {"turbinecode": "", "part1": {}, "part2": {}, "part3": {}}
# 获取 turbinecode 值(从第二列获取)
turbine_index = model.index(0, 1, folder_index) # 第一行第二列
if turbine_index.isValid():
new_value = model.data(turbine_index)
print(f"更新 turbinecode: {json_data[folder_name]['turbinecode']} -> {new_value}")
json_data[folder_name]["turbinecode"] = new_value
# 更新parts
for part_num in range(1, 4):
part_index = model.index(part_num, 0, folder_index)
if part_index.isValid():
code_index = model.index(0, 1, part_index)
if code_index.isValid():
json_data[folder_name][f"part{part_num}"]["code"] = model.data(code_index, Qt.DisplayRole)
class DirectSaveDelegate(QStyledItemDelegate):
"""直接保存的委托实现"""
def __init__(self, save_callback, parent=None):
super().__init__(parent)
self.save_callback = save_callback
def setModelData(self, editor, model, index):
try:
# 提交数据前验证索引
if not index.isValid():
print("⚠️ 无效的模型索引")
return
old_value = index.data(Qt.DisplayRole)
super().setModelData(editor, model, index)
new_value = index.data(Qt.DisplayRole)
print(f"📝 数据变更: {old_value}{new_value}")
# 获取顶层文件夹索引
top_index = index
while top_index.parent().isValid():
top_index = top_index.parent()
if model.hasIndex(top_index.row(), top_index.column(), top_index.parent()):
folder_name = model.data(top_index, Qt.DisplayRole)
self.save_callback(folder_name)
except Exception as e:
print(f"❌ 委托错误: {str(e)}")
import traceback
traceback.print_exc()
class FolderBrowser(QWidget):
"""文件夹浏览编辑主窗口"""
data_changed = Signal(dict) # 数据变更信号
def __init__(self, parent=None):
super().__init__(parent)
self.output_path = QDir.currentPath() # 默认输出路径
self.json_data = {} # 存储所有JSON数据
self.folder_map = {} # 文件夹路径映射
self.init_ui()
self.setup_connections()
def init_ui(self):
"""初始化用户界面"""
main_layout = QHBoxLayout(self)
splitter = QSplitter(Qt.Horizontal)
# 左侧文件夹树视图
self.left_model = QStandardItemModel()
self.left_model.setHorizontalHeaderLabels(["Folder Structure"])
self.left_tree = QTreeView()
self.left_tree.setModel(self.left_model)
self.left_tree.setEditTriggers(QTreeView.NoEditTriggers)
# 添加上下文菜单(复制功能)
self.left_tree.setContextMenuPolicy(Qt.ActionsContextMenu)
copy_action = QAction("Copy", self.left_tree)
copy_action.triggered.connect(self.copy_left_tree_text)
self.left_tree.addAction(copy_action)
# 右侧可编辑树视图
self.right_model = QStandardItemModel()
self.right_model.setHorizontalHeaderLabels(["Name", "Value"])
self.right_tree = QTreeView()
self.right_tree.setModel(self.right_model)
self.right_tree.setItemDelegate(
DirectSaveDelegate(self.handle_immediate_save, self.right_tree)
)
# 添加到分割器
splitter.addWidget(self.left_tree)
splitter.addWidget(self.right_tree)
splitter.setSizes([300, 500])
main_layout.addWidget(splitter)
def handle_immediate_save(self, folder_name):
print(f"🔧 保存触发 [{folder_name}]")
try:
# 安全获取文件夹索引
matches = self.right_model.match(
self.right_model.index(0, 0),
Qt.DisplayRole,
folder_name,
hits=1,
flags=Qt.MatchExactly
)
if not matches:
print(f"❌ 找不到文件夹: {folder_name}")
return
folder_index = matches[0]
# 获取 turbinecode 值(使用标准模型访问方式)
turbine_index = self.right_model.index(0, 1, folder_index)
turbine_value = self.right_model.data(turbine_index, Qt.DisplayRole)
print(f"📊 当前值 - turbinecode: {turbine_value or '<空>'}")
# 更新数据
TreeModelManager.update_json_from_model(self.right_model, self.json_data)
self.save_to_json(folder_name)
except Exception as e:
print(f"❌ 保存错误: {str(e)}")
def setup_connections(self):
"""设置信号和槽的连接"""
self.right_model.dataChanged.connect(self.on_right_data_changed)
self.left_tree.expanded.connect(self.sync_right_tree_expand)
self.left_tree.collapsed.connect(self.sync_right_tree_collapse)
self.right_tree.expanded.connect(self.sync_left_tree_expand)
self.right_tree.collapsed.connect(self.sync_left_tree_collapse)
def refresh_views(self):
"""刷新左右视图显示"""
self.left_tree.setModel(None) # 先重置模型
self.left_tree.setModel(self.left_model)
self.right_tree.setModel(None)
self.right_tree.setModel(self.right_model)
# 展开第一层节点
for i in range(self.left_model.rowCount()):
self.left_tree.expand(self.left_model.index(i, 0))
self.right_tree.expand(self.right_model.index(i, 0))
def copy_left_tree_text(self):
"""复制左侧树选中的文本"""
index = self.left_tree.currentIndex()
if index.isValid():
text = self.left_model.data(index, Qt.DisplayRole)
QApplication.clipboard().setText(text)
def sync_right_tree_expand(self, index):
"""同步右侧树的展开状态(仅第一层)"""
if not index.parent().isValid(): # 只处理第一层
right_index = self.right_model.index(index.row(), 0)
self.right_tree.expand(right_index)
def sync_right_tree_collapse(self, index):
"""同步右侧树的折叠状态(仅第一层)"""
if not index.parent().isValid(): # 只处理第一层
right_index = self.right_model.index(index.row(), 0)
self.right_tree.collapse(right_index)
def sync_left_tree_expand(self, index):
"""同步左侧树的展开状态(仅第一层)"""
if not index.parent().isValid(): # 只处理第一层
left_index = self.left_model.index(index.row(), 0)
self.left_tree.expand(left_index)
def sync_left_tree_collapse(self, index):
"""同步左侧树的折叠状态(仅第一层)"""
if not index.parent().isValid(): # 只处理第一层
left_index = self.left_model.index(index.row(), 0)
self.left_tree.collapse(left_index)
def set_output_path(self, path):
"""设置JSON文件输出路径"""
self.output_path = path
if not os.path.exists(path):
os.makedirs(path)
def set_initial_folders(self, folder_list):
"""初始化文件夹结构"""
self.left_model.clear()
self.right_model.clear()
self.left_model.setHorizontalHeaderLabels(["Folder Structure"])
self.right_model.setHorizontalHeaderLabels(["Name", "Value"])
self.json_data = {}
self.folder_map = {}
if not folder_list: # 添加空列表检查
print("Warning: folder_list is empty")
return
self.folder_map = {} # 新增: {文件夹名: 初始文件名}
for folder_path in folder_list:
folder_name = os.path.basename(folder_path)
# 使用初始 turbinecode 作为固定文件名
initial_code = folder_name.replace("机组", "").strip()
self.folder_map[folder_name] = f"{initial_code}.json" # 存储固定文件名
# 创建左侧树模型
self.left_model, self.folder_map = TreeModelManager.create_left_tree_model(folder_list)
# 创建右侧树模型
folder_names = [os.path.basename(f) for f in folder_list]
self.right_model, self.json_data = TreeModelManager.create_right_tree_model(folder_names)
# 初始化JSON文件
for folder_name in folder_names:
self.initialize_json_file(folder_name)
self.refresh_views() # 添加视图刷新
def initialize_json_file(self, folder_name):
"""初始化JSON文件"""
if not hasattr(self, 'output_path') or not self.output_path:
QMessageBox.warning(self, "Warning", "Output path not set!")
return
json_filename = self.get_json_file_path(folder_name)
# 如果文件已存在,则读取现有数据
if os.path.exists(json_filename):
existing_data = JsonFileHandler.read_json(json_filename)
if existing_data:
self.json_data[folder_name].update(existing_data)
print(f"加载已有json文件: {json_filename},{existing_data}")
TreeModelManager.update_model_from_json(
self.right_model, folder_name, self.json_data
)
else:
# 创建新JSON文件
self.save_to_json(folder_name)
def get_json_file_path(self, folder_name):
"""
获取JSON文件路径
规则: 使用原始文件夹名 + .json后缀保存到输出目录
"""
# 确保文件夹名是有效的文件名
safe_name = folder_name.strip()
# 只添加.json后缀不做其他修改
if not safe_name.lower().endswith('.json'):
safe_name += '.json'
return os.path.join(self.output_path, safe_name)
def on_right_data_changed(self, top_left, bottom_right):
folder_item = self.right_model.itemFromIndex(top_left)
while folder_item and folder_item.parent() is not None:
folder_item = folder_item.parent()
print(f"开始更改")
if folder_item:
folder_name = folder_item.text()
print(f"变更检测到文件夹:{folder_name}")
# 调试:打印变更前的数据
print("变更前数据:", self.json_data.get(folder_name))
# 更新数据
TreeModelManager.update_json_from_model(self.right_model, self.json_data)
# 调试:打印变更后的数据
print("变更后数据:", self.json_data.get(folder_name))
self.save_to_json(folder_name)
self.data_changed.emit(self.json_data)
def save_to_json(self, folder_name):
json_path = self.get_json_file_path(folder_name)
print(f"🛠️ 准备保存到: {json_path}")
# 验证路径
if os.path.isdir(json_path):
print(f"❌ 错误:路径是目录,自动添加.json后缀")
json_path += '.json'
try:
# 确保目录存在
os.makedirs(os.path.dirname(json_path), exist_ok=True)
# 写入文件
with open(json_path, 'w', encoding='utf-8') as f:
json.dump(self.json_data[folder_name], f, ensure_ascii=False, indent=4)
print(f"✅ 成功保存: {json_path}")
return True
except Exception as e:
print(f"❌ 保存失败: {str(e)}")
return False
def batch_update_folders(self, folder_mapping):
"""批量更新文件夹结构"""
for folder_name, new_data in folder_mapping.items():
if folder_name in self.json_data:
self.json_data[folder_name].update(new_data)
TreeModelManager.update_model_from_json(
self.right_model, folder_name, self.json_data
)
self.save_to_json(folder_name)
self.data_changed.emit(self.json_data)
def get_output_path(self):
"""获取当前输出路径"""
return self.output_path
def get_current_data(self):
"""获取当前所有数据"""
return self.json_data

View File

@ -204,4 +204,87 @@ SPLITTER_STYLE = """
QSplitter::handle:hover {
background: #808080; /* 鼠标悬停时颜色 */
}
"""
# ====================== QMessageBox 样式宏定义 ======================
# 基础消息框样式
MESSAGE_BOX_STYLE = f"""
QMessageBox {{
font-family: "{FONT_FAMILY}";
font-size: {CONTENT_FONT_SIZE}pt;
background-color: {LIGHT_COLOR};
color: {TEXT_COLOR};
}}
QMessageBox QLabel {{
{LABEL_STYLE}
min-width: 300px;
min-height: 60px;
}}
QMessageBox QPushButton {{
{BUTTON_STYLE}
min-width: 80px;
}}
"""
# 信息消息框样式
INFO_MESSAGE_BOX_STYLE = f"""
{MESSAGE_BOX_STYLE}
QMessageBox {{
border-top: 4px solid {ACCENT_COLOR};
}}
QMessageBox QLabel[text^="<html>"] {{
color: {PRIMARY_COLOR};
}}
"""
# 警告消息框样式
WARNING_MESSAGE_BOX_STYLE = f"""
{MESSAGE_BOX_STYLE}
QMessageBox {{
border-top: 4px solid #f39c12;
}}
QMessageBox QLabel[text^="<html>"] {{
color: #e67e22;
}}
"""
# 错误消息框样式
CRITICAL_MESSAGE_BOX_STYLE = f"""
{MESSAGE_BOX_STYLE}
QMessageBox {{
border-top: 4px solid #e74c3c;
}}
QMessageBox QLabel[text^="<html>"] {{
color: #c0392b;
}}
"""
# 提问消息框样式
QUESTION_MESSAGE_BOX_STYLE = f"""
{MESSAGE_BOX_STYLE}
QMessageBox {{
border-top: 4px solid {SUCCESS_COLOR};
}}
QMessageBox QLabel[text^="<html>"] {{
color: {SECONDARY_COLOR};
}}
"""
# 消息框按钮样式
MESSAGE_BOX_BUTTON_STYLE = f"""
QMessageBox QPushButton {{
{PRIMARY_BUTTON_STYLE}
min-width: 80px;
max-width: 120px;
}}
QMessageBox QPushButton[text="Yes"],
QMessageBox QPushButton[text="OK"] {{
background-color: {SUCCESS_COLOR};
color: {LIGHT_TEXT_COLOR};
}}
QMessageBox QPushButton[text="No"],
QMessageBox QPushButton[text="Cancel"] {{
background-color: #e74c3c;
color: {LIGHT_TEXT_COLOR};
}}
"""