将颜色设置为 QTableView 行

Posted

技术标签:

【中文标题】将颜色设置为 QTableView 行【英文标题】:Set color to a QTableView row 【发布时间】:2012-04-30 11:24:37 【问题描述】:
void MyWindow::initializeModelBySQL(QSqlQueryModel *model,QTableView *table,QString sql)
        model = new QSqlQueryModel(this);
        model->setQuery(sql);

通过这种方法,我可以为我的 QTableviews 设置一个 QSQlQueryModels。

但是如何根据单元格值为一行设置颜色?

【问题讨论】:

【参考方案1】:

视图根据单元格的Qt::BackgroundRole 角色绘制背景,该角色是QAbstractItemModel::data(index, role) 针对该角色返回的QBrush 值。

您可以将QSqlQueryModel 子类化以重新定义data() 以返回您计算的颜色,或者如果您的Qt > 4.8,您可以使用QIdentityProxyModel

class MyModel : public QIdentityProxyModel

    QColor calculateColorForRow(int row) const 
        ...
    

    QVariant data(const QModelIndex &index, int role)
    
        if (role == Qt::BackgroundRole) 
           int row = index.row();
           QColor color = calculateColorForRow(row);           
           return QBrush(color);
        
        return QIdentityProxyModel::data(index, role);
    
;

并在视图中使用该模型,并将 sql 模型设置为 QIdentityProxyModel::setSourceModel 的源。

您可以保持模型不变,并使用QAbstractItemView::setItemDelegate 在视图上设置委托来修改背景:

class BackgroundColorDelegate : public QStyledItemDelegate 

public:
    BackgroundColorDelegate(QObject *parent = 0)
        : QStyledItemDelegate(parent)
    
    
    QColor calculateColorForRow(int row) const;

    void initStyleOption(QStyleOptionViewItem *option,
                         const QModelIndex &index) const
    
        QStyledItemDelegate::initStyleOption(option, index);

        QStyleOptionViewItemV4 *optionV4 =
                qstyleoption_cast<QStyleOptionViewItemV4*>(option);

        optionV4->backgroundBrush = QBrush(calculateColorForRow(index.row()));
    
;

由于最后一种方法从 C++ 代码翻译并不总是很明显,这里是 python 中的等价物:

def initStyleOption(self, option, index):
    super(BackgroundColorDelegate,self).initStyleOption(option, index)
    option.backgroundBrush = calculateColorForRow(index.row())

【讨论】:

+1 代表解决方案的参考。我忘记了。 我需要为表列的每个值设置颜色(选择名称,来自用户的状态)在这种情况下为“状态”您可以编辑此代码。 optionV4->backgroundBrush = QBrush(calculateColorForRow(index.row()));它会产生错误 @Tineo 我忘记了 calculateColor... 函数必须是 const。要从模型中获取状态,您可以使用index-&gt;sibling(index-&gt;row(), 1 /* the column # for status */),因此,您可能需要将const QModelIndex &amp; index 而不是int row 传递给函数。 更改任何单元格颜色后,单元格不会自动更新/重绘。可以通过在 QTableView 上调用 update (index),或者从 QTableView 的子类发出或调用 dataChanged (index, index) 来强制更新。 (感谢to)【参考方案2】:

最好的办法是定义一个自定义模型(QAbstractTableModel 子类)。您可能希望拥有一个 QSqlQueryModel 作为此自定义类的成员。

如果是只读模型,至少需要实现这些方法:

 int rowCount(const QModelIndex &parent) const;
 int columnCount(const QModelIndex &parent) const;
 QVariant data(const QModelIndex &index, int role) const;

对于表现良好的模型也是如此

 QVariant headerData(int section, Qt::Orientation orientation, int role) const;

如果您需要模型能够编辑/提交数据,事情会涉及更多,您还需要实现这些方法:

 Qt::ItemFlags flags(const QModelIndex &index) const;
 bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole);
 bool insertRows(int position, int rows, const QModelIndex &index=QModelIndex());
 bool removeRows(int position, int rows, const QModelIndex &index=QModelIndex()); 

真正改变行外观的是这个方法的返回值:

 QVariant data(const QModelIndex &index, int role) const;

一个愚蠢的例子:

 QVariant MyCustomModel::data(const QModelIndex &index, int role) const
 
     if ( !index.isValid() )
         return QVariant();

     int row = index.row();
     int col = index.column();


     switch ( role )
     

        case Qt::BackgroundRole:
        
            if(somecondition)
               // background for this row,col is blue
               return QVariant(QBrush (QColor(Qt::blue)));
            
            // otherwise background is white
            return QVariant(QBrush (QColor(Qt::white)));
        

        case Qt::DisplayRole:
        
           // return actual content for row,col here, ie. text, numbers

        

        case Qt::TextAlignmentRole:
        

           if (1==col)
              return QVariant ( Qt::AlignVCenter | Qt::AlignLeft );

           if (2==col)
              return QVariant ( Qt::AlignVCenter | Qt::AlignTrailing );

           return QVariant ( Qt::AlignVCenter | Qt::AlignHCenter );

        
     

  

【讨论】:

以上是关于将颜色设置为 QTableView 行的主要内容,如果未能解决你的问题,请参考以下文章

QTableView中修改某个单元格或者行或者列内容颜色

Qt 中 QTableView 中如何设置某一单元格文本的颜色值,希望能贴出代码。

QTableview 怎样用 stylesheet 实现 选中行背景色保持原有颜色不变,但是加粗选中行边框

如何在 QTableview 单元格的值更新后及时为它的颜色设置动画?

如何在 Qt 中使用 QFileSystemModel 设置文本颜色 QTableView?

wpf里ListView怎么设置选中行的颜色