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

如何获取QWidget样式表中::hover状态的QPalette颜色?

获取QWidget hover状态下样式表设置的QPalette颜色问题

我编写了一段极简代码,用于打印QSpinBox在默认、hover和disabled状态下的QPalette颜色,但hover状态的颜色无法正确获取。

测试代码

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QWidget* widget = new QWidget();
    widget->setObjectName("widget");
    QSpinBox* spinBox = new QSpinBox();
    spinBox->setObjectName("spinBox");
    QTextEdit* textEdit = new QTextEdit();
    textEdit->setFixedSize(60, 20);
    QHBoxLayout* layout = new QHBoxLayout(widget);
    layout->addWidget(spinBox);
    layout->addWidget(textEdit); // random widget to have something else to grab focus

    widget->setStyleSheet(R"(
#spinBox
{
    background-color: rgba(1, 1, 1, 255);
    color: rgba(1, 1, 1, 255);
}
#spinBox::hover
{
    background-color: rgba(2, 2, 2, 255);
    color: rgba(2, 2, 2, 255);
}
#spinBox::disabled
{
    background-color: rgba(3, 3, 3, 255);
    color: rgba(3, 3, 3, 255);
}
    )");
    widget->show();

    static const auto colorToString = [](const QColor& color) -> QString
    {
        return QString("rgba: %1, %2, %3, %4").arg(color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha());
    };

    static const auto printPallete = [](const QPalette& pal)
    {
        #define qq qDebug().noquote().nospace()
        qq << "\n ------ state ------\n"        << pal.currentColorGroup();
        qq << "\color\n"                        << colorToString(pal.color(QPalette::ButtonText));
        qq << "\nbackground-color\n"            << colorToString(pal.color(QPalette::Window));
    };
    QObject::connect(new QShortcut(QKeySequence(Qt::Key_F1), widget), &QShortcut::activated, [&]
    {
        spinBox->setEnabled(true);
        printPallete(spinBox->palette());
    });
    QObject::connect(new QShortcut(QKeySequence(Qt::Key_F2), widget), &QShortcut::activated, [&]
    {
        spinBox->setEnabled(false);
        printPallete(spinBox->palette());
    });
    return a.exec();
}

测试情况

  • 未hover QSpinBox时按F1,输出默认状态的QPalette颜色(rgba:1,1,1,255);
  • hover QSpinBox时按F1,输出仍为默认状态颜色,无法获取样式表中设置的rgba:2,2,2,255;
  • 按F2禁用QSpinBox时,可正确获取到disabled状态的rgba:3,3,3,255。

问题原因

QWidget的palette()方法返回的是基础状态的调色板,hover属于动态伪状态(临时状态),这类状态的样式表属性不会同步到QPalette中。Qt的样式表和QPalette是两套并行的样式系统:只有disabled这种持久状态会更新到QPalette,而hover这类临时状态的样式仅在绘制阶段生效,不会修改widget的palette对象。

解决方法

方法1:通过QStyle计算指定状态的样式值

利用Qt的样式系统,构造包含hover状态的样式选项,让样式计算对应状态下的属性值,这是官方推荐的标准方式:

// 替换原有F1快捷键的槽函数逻辑
QObject::connect(new QShortcut(QKeySequence(Qt::Key_F1), widget), &QShortcut::activated, [&]
{
    spinBox->setEnabled(true);
    static const auto colorToString = [](const QColor& color) -> QString
    {
        return QString("rgba: %1, %2, %3, %4").arg(color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha());
    };

    // 构造SpinBox的样式选项,并添加hover状态
    QStyleOptionSpinBox opt;
    spinBox->initStyleOption(&opt);
    opt.state |= QStyle::State_MouseOver;

    // 获取hover状态下的background-color和color
    QColor hoverBg = spinBox->style()->styleSheetProperty(spinBox, "background-color", opt.state);
    QColor hoverText = spinBox->style()->styleSheetProperty(spinBox, "color", opt.state);

    qDebug().noquote() << "\n ------ hover state ------";
    qDebug().noquote() << "color:" << colorToString(hoverText);
    qDebug().noquote() << "background-color:" << colorToString(hoverBg);

    // 同时打印默认状态的palette(可选)
    qDebug().noquote() << "\n ------ default state ------";
    printPallete(spinBox->palette());
});

方法2:手动解析样式表字符串

如果样式表结构简单固定,也可以直接解析样式表文本提取对应伪状态的属性值。但这种方法适应性差,样式表结构变化时需要同步修改解析逻辑:

// 在需要获取hover颜色的地方添加以下代码
QString styleSheet = spinBox->styleSheet();
static const auto colorToString = [](const QColor& color) -> QString
{
    return QString("rgba: %1, %2, %3, %4").arg(color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha());
};

// 正则匹配hover状态的样式
QRegularExpression hoverRegex(R"(#spinBox::hover\s*\{\s*background-color:\s*rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+)\);\s*color:\s*rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+)\);\s*\})");
QRegularExpressionMatch match = hoverRegex.match(styleSheet);
if (match.hasMatch()) {
    QColor hoverBg(
        match.captured(1).toInt(),
        match.captured(2).toInt(),
        match.captured(3).toInt(),
        match.captured(4).toInt()
    );
    QColor hoverText(
        match.captured(5).toInt(),
        match.captured(6).toInt(),
        match.captured(7).toInt(),
        match.captured(8).toInt()
    );
    qDebug().noquote() << "\n ------ parsed hover state ------";
    qDebug().noquote() << "color:" << colorToString(hoverText);
    qDebug().noquote() << "background-color:" << colorToString(hoverBg);
}

注意事项

  • 优先使用方法1,它能正确处理样式继承、优先级、嵌套等复杂场景;
  • 不要尝试通过修改QPalette来同步样式表的hover状态,两套系统设计上相互独立,强行同步会导致样式冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:54:53