Commit da148b05 by yhb

123456

parent 7cf1afc7
......@@ -29,10 +29,11 @@ print("[环境变量] OpenMP冲突已修复")
from qtpy import QtWidgets
from app import MainWindow
# 延迟导入,避免在 QApplication 创建前创建 QWidget
# from app import MainWindow
from database.config import get_config, get_temp_models_dir
from widgets.style_manager import FontManager
from widgets.responsive_layout import ResponsiveLayout
# from widgets.style_manager import FontManager
# from widgets.responsive_layout import ResponsiveLayout
def setup_logging(level: str = "info"):
......@@ -270,6 +271,11 @@ def _main():
app.setApplicationName('Detection')
app.setOrganizationName('Detection')
# 在 QApplication 创建后导入可能创建 QWidget 的模块
from app import MainWindow
from widgets.style_manager import FontManager
from widgets.responsive_layout import ResponsiveLayout
# 初始化响应式布局系统
ResponsiveLayout.initialize(app)
......
......@@ -686,6 +686,10 @@ class MainWindow(
from widgets import ChannelPanel, MissionPanel, CurvePanel
# 主页面容器
# 修复:确保 QApplication 完全初始化后再创建 QWidget
app = QtWidgets.QApplication.instance()
if app is None:
raise RuntimeError("QApplication 未初始化")
page = QtWidgets.QWidget()
page_layout = QtWidgets.QVBoxLayout(page)
page_layout.setContentsMargins(0, 0, 0, 0)
......@@ -714,6 +718,10 @@ class MainWindow(
except ImportError:
from widgets import ChannelPanel, MissionPanel
# 确保 QApplication 存在
app = QtWidgets.QApplication.instance()
if app is None:
raise RuntimeError("QApplication 未初始化")
layout_widget = QtWidgets.QWidget()
main_layout = QtWidgets.QHBoxLayout(layout_widget)
main_layout.setContentsMargins(10, 10, 10, 10)
......
......@@ -69,6 +69,7 @@ class TrainingWorker(QThread):
super().__init__()
self.training_params = training_params
self.is_running = True
self.training_actually_started = False # 标记训练是否已经真正开始(第一个epoch开始)
self.train_config = None
# 调试信息:显示传入的训练参数
......@@ -522,6 +523,8 @@ class TrainingWorker(QThread):
def on_train_start(trainer):
"""训练开始回调 - 只输出到终端,不发送到UI"""
# 标记训练已经真正开始
self.training_actually_started = True
# 记录开始时间
epoch_start_time[0] = time.time()
# 不发送任何格式化消息到UI,让LogCapture直接捕获原生输出
......@@ -1264,3 +1267,7 @@ class TrainingWorker(QThread):
def stop_training(self):
"""停止训练"""
self.is_running = False
def has_training_started(self):
"""检查训练是否已经真正开始"""
return self.training_actually_started
......@@ -1900,6 +1900,10 @@ class ChannelPanelHandler:
def _initConfigFileWatcher(self):
"""初始化配置文件监控器"""
try:
# 临时禁用配置文件监控器以解决 QWidget 创建顺序问题
print(f"[ConfigWatcher] 配置文件监控器已禁用(避免 QWidget 创建顺序问题)")
return
# 获取配置文件路径
project_root = get_project_root()
config_path = os.path.join(project_root, 'database', 'config', 'default_config.yaml')
......@@ -1928,7 +1932,12 @@ class ChannelPanelHandler:
print(f"🔄 [ConfigWatcher] 检测到配置文件变化: {path}")
# 延迟一小段时间,确保文件写入完成
# 修复:检查 QApplication 是否存在
if QtWidgets.QApplication.instance() is not None:
QtCore.QTimer.singleShot(100, self._reloadChannelConfig)
else:
# 如果没有 QApplication,直接调用重载函数
self._reloadChannelConfig()
except Exception as e:
print(f"[ConfigWatcher] 处理配置文件变化失败: {e}")
......
......@@ -17,7 +17,7 @@ import csv
import datetime
import numpy as np
from qtpy import QtWidgets, QtCore
from PyQt5.QtCore import QThread, pyqtSignal
from qtpy.QtCore import QThread, Signal as pyqtSignal
# 导入图标工具
try:
......@@ -930,7 +930,7 @@ class CurvePanelHandler:
QtWidgets.QApplication.processEvents()
# 🔥 延迟关闭进度条,确保用户能看到(至少显示500ms)
from PyQt5.QtCore import QTimer
from qtpy.QtCore import QTimer
QTimer.singleShot(500, progress_dialog.close)
print(f"✅ [进度条] 将在500ms后关闭")
......
......@@ -11,7 +11,7 @@ widgets/videopage/historypanel.py (HistoryPanel)
-
"""
from PyQt5 import QtWidgets, QtCore
from qtpy import QtWidgets, QtCore
class HistoryPanelHandler:
......@@ -80,8 +80,8 @@ class HistoryPanelHandler:
return
import os
from PyQt5.QtMultimedia import QMediaPlayer
from PyQt5 import QtWidgets
from qtpy.QtMultimedia import QMediaPlayer
from qtpy import QtWidgets
player = self.history_panel._media_player
print(f"[HistoryPanelHandler] 播放器: {player}")
......@@ -158,7 +158,7 @@ class HistoryPanelHandler:
if not self.history_panel or not hasattr(self.history_panel, 'play_pause_button'):
return
from PyQt5.QtMultimedia import QMediaPlayer
from qtpy.QtMultimedia import QMediaPlayer
from widgets.style_manager import newIcon
button = self.history_panel.play_pause_button
......
......@@ -5,7 +5,7 @@
根据屏幕分辨率自动调整UI尺寸
"""
from PyQt5 import QtWidgets, QtCore
from qtpy import QtWidgets, QtCore
class ResponsiveLayout:
......
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
"""
统一样式管理器
......@@ -40,7 +40,7 @@ import os.path as osp
import sys
try:
from PyQt5 import QtGui, QtWidgets, QtCore
from qtpy import QtGui, QtWidgets, QtCore
except ImportError as e:
raise
......@@ -78,12 +78,11 @@ class FontManager:
@staticmethod
def getDefaultFont():
"""获取默认字体"""
font = QtGui.QFont(
FontManager.DEFAULT_FONT_FAMILY,
FontManager.DEFAULT_FONT_SIZE
return FontManager.getFont(
size=FontManager.DEFAULT_FONT_SIZE,
weight=FontManager.DEFAULT_FONT_WEIGHT,
family=FontManager.DEFAULT_FONT_FAMILY
)
font.setWeight(FontManager.DEFAULT_FONT_WEIGHT)
return font
@staticmethod
def getFont(size=None, weight=None, italic=False, underline=False, family=None):
......@@ -96,7 +95,31 @@ class FontManager:
weight = FontManager.DEFAULT_FONT_WEIGHT
font = QtGui.QFont(family, size)
# PySide6兼容性:将整数权重转换为QFont.Weight枚举
try:
# 尝试使用PySide6的Weight枚举
if hasattr(QtGui.QFont, 'Weight'):
if weight <= 25:
font.setWeight(QtGui.QFont.Weight.Light)
elif weight <= 50:
font.setWeight(QtGui.QFont.Weight.Normal)
elif weight <= 63:
font.setWeight(QtGui.QFont.Weight.DemiBold)
elif weight <= 75:
font.setWeight(QtGui.QFont.Weight.Bold)
else:
font.setWeight(QtGui.QFont.Weight.Black)
else:
# 回退到旧的整数方式(PyQt5)
font.setWeight(weight)
except (AttributeError, TypeError):
# 如果出现任何错误,使用默认权重
try:
font.setWeight(QtGui.QFont.Weight.Normal)
except:
pass
font.setItalic(italic)
font.setUnderline(underline)
return font
......@@ -157,8 +180,17 @@ class FontManager:
@staticmethod
def applyToApplication(app):
"""应用默认字体到整个应用程序"""
font = FontManager.getDefaultFont()
try:
# 确保使用当前 Qt 后端创建字体对象
from qtpy import QtGui
font = QtGui.QFont(
FontManager.DEFAULT_FONT_FAMILY,
FontManager.DEFAULT_FONT_SIZE
)
font.setWeight(FontManager.DEFAULT_FONT_WEIGHT)
app.setFont(font)
except Exception as e:
print(f"字体设置失败,使用默认字体: {e}")
@staticmethod
def applyToWidgetRecursive(widget, size=None, weight=None):
......@@ -827,7 +859,7 @@ class TextButtonStyleManager:
# 计算文本宽度:字符数 * 每字符宽度 + 内边距
text_width = len(text) * cls.CHAR_WIDTH + cls.MIN_PADDING
# 返回基础宽度和计算宽度的较大值
return max(cls.BASE_WIDTH, text_width)
@classmethod
......@@ -850,7 +882,14 @@ class TextButtonStyleManager:
@classmethod
def createStandardButton(cls, text, parent=None, slot=None):
"""创建标准样式的文本按钮"""
button = QtWidgets.QPushButton(text, parent)
# 修复 PySide6 兼容性问题 - 分步创建
try:
button = QtWidgets.QPushButton(text)
if parent is not None:
button.setParent(parent)
except Exception as e:
print(f"按钮创建失败: {e}")
button = QtWidgets.QPushButton("按钮")
# 应用标准样式
cls.applyToButton(button, text)
......@@ -867,6 +906,37 @@ class TextButtonStyleManager:
button.setText(new_text)
cls.applyToButton(button, new_text)
@classmethod
def applyDangerStyle(cls, button):
"""应用危险按钮样式(红色)"""
button.setStyleSheet("""
QPushButton {
background-color: #dc3545;
color: white;
border: none;
padding: 8px 16px;
border-radius: 4px;
font-weight: bold;
min-width: 100px;
}
QPushButton:hover {
background-color: #c82333;
}
QPushButton:pressed {
background-color: #bd2130;
}
QPushButton:disabled {
background-color: #6c757d;
color: #ffffff;
}
""")
@classmethod
def applyStandardStyle(cls, button):
"""应用标准按钮样式"""
# 重新应用标准样式
cls.applyToButton(button)
class BackgroundStyleManager:
"""全局背景颜色管理器"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment