模仿 QApplication::palette() 基于颜色样式的行为
Mimic QApplication::palette() based color style behavior
很简单:我想在不禁用的情况下模仿被禁用的项目的颜色变化。
有 QTableWidgetItem
和 QStandardItem
项,我正在使用这样的代码
item->setForeground( enabled ? QApplication::palette().color( QPalette::Text ) : QApplication::palette().color( QPalette::Disabled, QPalette::Text ) );
现在。但是,如果用户使用新调色板调用 QApplication::setPalette( ... )
,则必须手动刷新该项目。我宁愿设置一个 ColorGroup
和 Role
,这样 Qt 就知道如何刷新。可以吗?
要实现自动化,您必须覆盖 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();
}
很简单:我想在不禁用的情况下模仿被禁用的项目的颜色变化。
有 QTableWidgetItem
和 QStandardItem
项,我正在使用这样的代码
item->setForeground( enabled ? QApplication::palette().color( QPalette::Text ) : QApplication::palette().color( QPalette::Disabled, QPalette::Text ) );
现在。但是,如果用户使用新调色板调用 QApplication::setPalette( ... )
,则必须手动刷新该项目。我宁愿设置一个 ColorGroup
和 Role
,这样 Qt 就知道如何刷新。可以吗?
要实现自动化,您必须覆盖 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();
}