【问题标题】:Mimic QApplication::palette() based color style behavior模仿基于 QApplication::palette() 的颜色样式行为
【发布时间】:2023-03-11 13:15:01
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: c++ qt qt5 qtablewidget qpalette


    【解决方案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 提出一个新问题
    猜你喜欢
    • 2020-03-29
    • 2021-10-15
    • 2011-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多