You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide6程序在QThreadPool运行QRunnable时Hover自定义按钮崩溃

解决方案(适配Python3.9.9 + PySide6 v6.4.1)

针对你遇到的自定义按钮hover时程序崩溃的问题,以下是几个可行的修复方案,均适配旧版本环境:

方案1:调用父类paintEvent处理基础状态

你的自定义paintEvent完全覆盖了父类实现,导致Qt内部的hover状态管理、绘图上下文清理等逻辑未执行,在并发场景下引发冲突。修改CustomButton的paintEvent:

def paintEvent(self, event: QPaintEvent):
    # 先让父类处理按钮的基础状态(包括hover标记、内部绘图资源)
    super().paintEvent(event)
    fill_color = QLinearGradient.Preset.TemptingAzure

    with QPainter(self) as p:
        p.setRenderHint(QPainter.RenderHint.Antialiasing)
        rect = event.rect()
        p.fillRect(rect, fill_color)

如果不需要保留父类的默认按钮样式,可以添加p.setCompositionMode(QPainter.CompositionMode_Source)实现完全覆盖绘制,但必须先调用父类paintEvent完成基础状态初始化。

方案2:禁用按钮的hover事件

如果业务不需要按钮的hover交互,可以直接关闭hover状态,避免触发冲突的重绘逻辑:

class CustomButton(QPushButton):
    def __init__(self, parent=None):
        super(CustomButton, self).__init__(parent)
        self.setFixedSize(650, 99)
        # 禁用hover事件,不会触发hover相关的重绘
        self.setAttribute(Qt.WA_Hover, False)

方案3:使用本地线程池替代全局实例

全局QThreadPool实例在旧版本PySide6中可能存在与UI线程的状态同步问题,改用本地线程池实例:

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        # ... 其他初始化代码 ...
        # 创建本地线程池实例
        self._thread_pool = QThreadPool()

    def _create_workers(self):
        for i in range(self._num_workers_to_create):
            worker = WorkerSleep()
            worker.signals.finished.connect(self._update_completed_workers)
            # 使用本地线程池启动任务
            self._thread_pool.start(worker)

方案4:手动创建渐变替代预设值

旧版本中QLinearGradient.Preset可能存在线程安全问题,手动创建渐变替代预设值:

def paintEvent(self, event: QPaintEvent):
    # 手动创建渐变,模拟TemptingAzure效果
    gradient = QLinearGradient(0, 0, self.width(), self.height())
    gradient.setColorAt(0, QColor(100, 181, 246))
    gradient.setColorAt(1, QColor(144, 202, 249))

    with QPainter(self) as p:
        p.setRenderHint(QPainter.RenderHint.Antialiasing)
        rect = event.rect()
        p.fillRect(rect, gradient)

问题原因

这是PySide6 v6.4.x版本的已知bug,涉及自定义控件paintEvent与QThreadPool并发操作时的绘图资源冲突:当后台线程触发UI更新信号时,大尺寸自定义按钮的hover重绘会触发内存访问错误。官方在v6.6.0版本中修复了该类线程与UI绘图的同步问题,因此升级后问题消失。

内容的提问来源于stack exchange,提问作者chris1656

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:43:27