模仿基于 QApplication::palette() 的颜色样式行为

Posted

技术标签:

【中文标题】模仿基于 QApplication::palette() 的颜色样式行为【英文标题】:Mimic QApplication::palette() based color style behavior 【发布时间】:2019-04-10 16:30:00 【问题描述】:

这很简单:我想在不禁用的情况下模拟禁用项目的颜色变化。

拥有QTableWidgetItemQStandardItem 项目,我正在使用这样的代码

item->setForeground( enabled ? QApplication::palette().color( QPalette::Text ) : QApplication::palette().color( QPalette::Disabled, QPalette::Text ) );

现在。但是,如果用户使用新调色板调用QApplication::setPalette( ... ),则必须手动刷新该项目。我宁愿设置ColorGroupRole,这样Qt 知道如何刷新。有可能吗?

【问题讨论】:

【参考方案1】:

要实现自动化,您必须覆盖 QStyledItemDelegate 的 initStyleOption() 方法,并将假启用与新角色相关联:

#include <QtWidgets>

enum FakeRoles 
    FakeEnableRole = Qt::UserRole + 1000
;

class ForegroundDelegate: public QStyledItemDelegate

public:
    using QStyledItemDelegate::QStyledItemDelegate;
protected:
    void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const override
        QStyledItemDelegate::initStyleOption(option, index);
        QVariant val = index.data(FakeRoles::FakeEnableRole);
        if(val.canConvert<bool>())
            bool enabled = val.value<bool>();
            option->palette.setBrush(QPalette::Text,
                                     QApplication::palette().color(enabled ? QPalette::Active:
                                                                             QPalette::Disabled, QPalette::Text));
        
    
;

int main(int argc, char *argv[])

    QApplication a(argc, argv);
    QTableWidget w(4, 4);
    ForegroundDelegate *delegate = new ForegroundDelegate(&w);
    w.setItemDelegate(delegate);
    for(int i=0; i< w.rowCount(); ++i)
        for (int j=0; j< w.columnCount(); ++j) 
            QTableWidgetItem *it = new QTableWidgetItem(QString("%1-%2").arg(i).arg(j));
            w.setItem(i, j, it);
            bool enabled =  QRandomGenerator::global()->bounded(0, 2) == 0;
            it->setData(FakeRoles::FakeEnableRole, enabled);
        
    w.show();
    QTimer::singleShot(1000, []()
        QPalette pal = QApplication::palette();
        pal.setColor(QPalette::Active, QPalette::Text, QColor("salmon"));
        pal.setColor(QPalette::Disabled, QPalette::Text, QColor("cyan"));
        QApplication::setPalette(pal);
    );
    return a.exec();

【讨论】:

这正是我要找的,非常感谢! 因此,虽然这对于 QTableWidget 示例来说效果很好,但当与 QComboBox 一起使用时,它似乎会覆盖除文本之外的所有样式选项。在某些情况下,它甚至似乎与项目的文本混淆。知道我在这里做错了什么吗? @DrPepperJo 如果没有minimal reproducible example 我无法指出你,我还假设视图使用 QStyledItemDelegate 作为委托,并且在 QListView、QTableView 和 QTreeView 的情况下使用它。在其他情况下,例如 QComboBox,可能只使用具有另一种样式的 QItemDelegate,因此在放置 QStyledItemDelegate 时,您正在更改 QComboBox 的默认样式。 @DrPepperJo 或者您的实现可能有另一个错误。您当前的问题非常集中:QTableWidget,这是正确的做法,因为我们在这里寻找精确的问题,所以最后我建议您使用 MCVE 提出一个新问题

以上是关于模仿基于 QApplication::palette() 的颜色样式行为的主要内容,如果未能解决你的问题,请参考以下文章

[ZooKeeper.net] 1 模仿dubbo实现一个简要的http服务的注册 基于webapi

仿人机器人的实时模仿(基于Kinect)

模仿iframe框架,由分隔栏动态改变左右两侧div大小———基于jQuery

javascript-- 基于jQuery的模仿移动端上拉加载更多控件

SylixOS 基于STM32平台的GPIO模仿I2C总线的驱动开发流程

在模仿中精进数据可视化:国内38城居住自由指数