我有一个带有自定义模型、委托和数据类的 QTableView。我想根据数据类型在表格中显示不同的小部件。这是在我的委托类中完成的。背景和复选框类型在我的模型类的 show 方法中处理。 这是棘手的部分!如果我在模型中的 show 方法的 DisplayRole 情况下返回数据值,我无法访问委托类中的数据类以使用它的类型 (return QVariant::fromValue(mData[column]); = > qvariant_cast(index.data()))。这样,我的复选框旁边就不会显示任何内容,因为我返回了数据类,而不是字符串。这也发生在我的数据类的值类型上。这种情况该如何处理?我是否应该将复选框移动到委托类并将其添加到那里并在其旁边添加文本值(如果是,如何处理简单的文本列?)?
这是一个示例,我的所有值都是 0,但复选框列中没有显示任何内容(我在上面解释了为什么会发生这种情况)
自定义数据:
class Data
{
public:
enum Colors { WHITE, RED, BLUE };
enum Types { VALUE, PICTURE, COMBO, COLOR, CHECKBOX, BUTTON };
Colors mColor;
Types mType;
bool isChecked;
double mValue;
Data() = default;
Data(Colors color, Types type);
QString getValue() const;
QColor getColor() const;
Types getType() const
};
自定义模型数据方法:
QVariant DataModel::data(const QModelIndex &index, int role) const
{
int column = index.column();
switch (role) {
case Qt::DisplayRole:
return QVariant::fromValue(mData[column]);
break;
case Qt::BackgroundColorRole:
return mData[column].getColor();
break;
case Qt::CheckStateRole:
if (mData[column].getType() == Data::Types::CHECKBOX) {
if (mData[column].isChecked) {
return Qt::Checked;
} else
return Qt::Unchecked;
break;
}
}
return QVariant();
}
自定义委托绘制方法:
void CustomDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.data().canConvert<Data>()) {
Data data = qvariant_cast<Data>(index.data());
switch (data.getType())
{
case Data::Types::COMBO : {
QStyleOptionComboBox box;
QString text = data.getValue();
box.currentText = text;
box.rect = option.rect;
QComboBox tmp;
QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &box, painter, &tmp);
QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &box, painter, 0);
break;
}
case Data::Types::BUTTON : {
QString text = data.getValue();
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &opt, painter);
QStyleOptionButton buttonOption;
buttonOption.text = text; //use emoji for text, optionally you can use icon + iconSize
QRect rect = option.rect;
rect = rect.marginsRemoved(QMargins(3, 3, 3, 3));
buttonOption.rect = rect;//QRect(option.rect.left()+option.rect.width()-(2*option.rect.height()),option.rect.top(),option.rect.height(),option.rect.height());
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOption, painter);
break;
}
case Data::Types::CHECKBOX: {
QString text = data.getValue();
DataModel *model= static_cast<DataModel>(index.model());
model->setData(index, QVariant::fromValue(text));
QStyledItemDelegate::paint(painter, option, index);
break;
}
case Data::Types::PICTURE:
case Data::Types::COLOR:
case Data::Types::VALUE:
QStyledItemDelegate::paint(painter, option, index);
break;
}
} else {
QStyledItemDelegate::paint(painter, option, index);
}
}
我试过了
case Qt::DisplayRole:
return QVariant::fromValue(mData[column].getValue());
break;
但它破坏了我的委托类在这一行
if (index.data().canConvert<Data>()) {
它总是返回 false,因为 index.data() 从上面返回 getvalue,它是一个字符串!
最简单的方法是让您的模型以不同于
Qt::EditRole
/Qt::DisplayRole
的角色返回 Type 值。您可以根据自己的目的自由使用从Qt::UserRole
开始的角色。
在您的情况下,返回
Data::Types
中的 Qt::UserRole
值,并让您的委托读取这些值,以便它知道它应该如何表现。