我有一个QTableView组件在行中显示几种类型的数据。我需要的是以不同的颜色显示每种类型的行。我的样式表看起来像这样:
RecordSheet::item {
border: 0px;
color: black;
padding: 1px 0px 0px 3px;
}
RecordSheet::item:selected, RecordSheet::item:selected:!active {
background-color: #e8b417;
color: black;
}
我有两个想法如何实现这个目标:
在模型中使用data()
方法并回复Qt::BackgroundColorRole
。不幸的是,当我这样做时,背景颜色会被忽略,直到我从样式表中删除border: 0px;
,当我删除边框时,样式面的填充将被忽略。奇怪...
为每种类型的行设置CSS / QSS类,并在样式表中设置它们的颜色。然后使用该模型为每种类型的行分配适当的类。所以样式表看起来像这样:
RecordSheet::item {
border: 0px;
color: black;
padding: 1px 0px 0px 3px;
}
RecordSheet::item[class=green_row] {
background-color: green;
}
RecordSheet::item[class=red_row] {
background-color: red;
}
我更喜欢这种方法,因为它将内容与外观分开,但我不知道如何做到这一点。也许使用ItemDelegate?
拜托,有没有人知道一个简单明了的解决方案?
亲切的问候和非常感谢。
扬
答案 0 :(得分:2)
你不需要样式表来做这件事,styleshhet不是那么强大,无法做开发人员想要的所有事情。使用更强大的东西 - 委托。我将向您展示主要想法和工作实例。部首:
#ifndef ITEMDELEGATEPAINT_H
#define ITEMDELEGATEPAINT_H
#include <QStyledItemDelegate>
class ItemDelegatePaint : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit ItemDelegatePaint(QObject *parent = 0);
ItemDelegatePaint(const QString &txt, QObject *parent = 0);
protected:
void paint( QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index ) const;
QSize sizeHint( const QStyleOptionViewItem &option,
const QModelIndex &index ) const;
QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget * editor, const QModelIndex & index) const;
void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const;
void updateEditorGeometry(QWidget * editor, const QStyleOptionViewItem & option, const QModelIndex & index) const;
signals:
public slots:
};
#endif // ITEMDELEGATEPAINT_H
这里有很多方法,但我只会给你画画,因为它对你来说是最重要的。有关您可以在web
中找到的其他方法的说明CPP:
void ItemDelegatePaint::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QString txt = index.model()->data( index, Qt::DisplayRole ).toString();
if(index.row() == 0)//green row
painter->fillRect(option.rect,QColor(0,255,0));
else
if(index.row() == 1)//blue row
painter->fillRect(option.rect,QColor(0,0,255));
else
if(index.row() == 2)//red row
painter->fillRect(option.rect,QColor(255,0,0));
//and so on
if( option.state & QStyle::State_Selected )//we need this to show selection
{
painter->fillRect( option.rect, option.palette.highlight() );
}
QStyledItemDelegate::paint(painter,option,index);//standard processing
}
用法:
ui->tableView->setItemDelegate(new ItemDelegatePaint);
结果:
答案 1 :(得分:0)
尽管QItemDelegate是一个不错的选择,但是当你想要做的只是为一些细胞着色时,有时它只是一个过度杀戮。 你可以这样做:
QStandardItem *item = new QStandardItem("");
item->setData(Qt::gray, Qt::BackgroundColorRole);
这对我来说很有效。
答案 2 :(得分:0)
做一个尽可能简单和快速的事情是一个好主意。如果数据外观是您的概念,则无需添加额外的项目委托类,只需更改data()
方法即可,它具有特定的作用,例如QT教程中的以下示例。
此方法适用于您不想更改数据(例如只读表)的情况,但是对于显示和编辑功能,@ Chernobyl提供了一个不错的解决方案QStyledItemDelegate
。
#ifndef MYMODEL_H
#define MYMODEL_H
#include <QAbstractTableModel>
class MyModel : public QAbstractTableModel
{
Q_OBJECT
public:
MyModel(QObject *parent);
int rowCount(const QModelIndex &parent = QModelIndex()) const override ;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
};
#endif // MYMODEL_H
#include <QFont>
#include <QBrush>
#include "mymodel.h"
#include <QDebug>
MyModel::MyModel(QObject *parent)
:QAbstractTableModel(parent)
{
}
int MyModel::rowCount(const QModelIndex & /*parent */) const
{
return 2;
}
int MyModel::columnCount(const QModelIndex & /*parent */) const
{
return 3;
}
//! [Quoting ModelView Tutorial]
// mymodel.cpp
QVariant MyModel::data(const QModelIndex &index, int role) const
{
int row = index.row();
int col = index.column();
// generate a log message when this method gets called
qDebug() << QString("row %1, col%2, role %3")
.arg(row).arg(col).arg(role);
switch(role){
case Qt::DisplayRole:
if (row == 0 && col == 1) return QString("<--left");
if (row == 1 && col == 1) return QString("right-->");
return QString("Row%1, Column%2")
.arg(row + 1)
.arg(col +1);
break;
case Qt::FontRole:
if (row == 0 && col == 0) //change font only for cell(0,0)
{
QFont boldFont;
boldFont.setBold(true);
return boldFont;
}
break;
case Qt::BackgroundRole:
if (row == 1 && col == 2) //change background only for cell(1,2)
{
QBrush redBackground(Qt::red);
return redBackground;
}
break;
case Qt::TextAlignmentRole:
if (row == 1 && col == 1) //change text alignment only for cell(1,1)
{
return Qt::AlignRight + Qt::AlignVCenter;
}
break;
case Qt::CheckStateRole:
if (row == 1 && col == 0) //add a checkbox to cell(1,0)
{
return Qt::Checked;
}
}
return QVariant();
}
//! [Quoting ModelView Tutorial]
答案 3 :(得分:0)
有一种方法可以按照方法2使用CSS。以下代码显示了如何根据单元格的内容对每个单元格进行样式化。但是我敢肯定,您可以弄清楚如何将其扩展到为连续的每个单元格设置样式。同样,它是使用pyqt用python编写的,但仍处于关闭状态。
final List<Path> allFiles = Files.newDirectoryStream(folder)
.sorted((a, b) -> { ... })
.collect(Collectors.toList());
boolean firstHasBeenProcessed = false;
for (final Path currentFile: allFiles) {
if (firstHasBeenProcessed) {
processAsFollowUpFile(currentFile);
} else {
processAsFirstFile(currentFile);
firstHasBeenProcessed = true;
}
}
关键是将具有适当属性的窗口小部件传递给#!/usr/bin/python3
from PyQt5 import QtWidgets, QtGui, QtCore
class_values = ["zero", "one", "two"]
class Cell(QtWidgets.QWidget):
def initFromItem(self, item):
self.setProperty('dataClass', class_values[int(item.text())])
class TDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, *a):
super(TDelegate, self).__init__(*a)
self.cell = Cell(self.parent())
def paint(self, painter, option, index):
item = index.model().itemFromIndex(index)
self.cell.initFromItem(item)
self.initStyleOption(option, index)
style = option.widget.style() if option.widget else QtWidgets.QApplication.style()
style.unpolish(self.cell)
style.polish(self.cell)
style.drawControl(QtWidgets.QStyle.CE_ItemViewItem, option, painter, self.cell)
class TTableModel(QtGui.QStandardItemModel):
def __init__(self, parent=None):
super(TTableModel, self).__init__(parent)
for i in range(5):
self.appendRow([QtGui.QStandardItem(str((x+i) % 3)) for x in range(5)])
class TTableView(QtWidgets.QTableView):
def __init__(self, parent=None):
super(TTableView, self).__init__(parent)
self.setItemDelegate(TDelegate(self))
class Main(QtWidgets.QMainWindow):
def __init__(self):
super(Main, self).__init__()
self.table = TTableView(self)
self.model = TTableModel(self)
self.table.setModel(self.model)
self.setCentralWidget(self.table)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyleSheet("""
Cell[dataClass=zero]::item { background-color: gray; }
Cell[dataClass=one]::item { background-color: green; }
Cell[dataClass=two]::itemn { background-color: cyan; }
""")
mainWin = Main()
mainWin.show()
sys.exit(app.exec_())
。 CSS也必须引用drawControl
才能发生任何事情。