我希望在Table视图的其中一列中有一个复选框。具体 - 在其中一行中,因为视图使用transposing proxy model。我使用QItemDelegate派生类来完成它,如文档and here中所述:
class checkBoxDelegate : public QItemDelegate
{
Q_OBJECT
public:
checkBoxDelegate(QAbstractItemView* parentView = NULL, QObject *parent = NULL);
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
void setEditorData(QWidget *editor, const QModelIndex &index) const Q_DECL_OVERRIDE;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const Q_DECL_OVERRIDE;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE;
void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const;
//QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
~checkBoxDelegate();
private:
QAbstractItemView* parentView;
};
checkBoxDelegate::checkBoxDelegate(QAbstractItemView* parentView, QObject *parent)
: QItemDelegate(parent), parentView(parentView)
{
}
checkBoxDelegate::~checkBoxDelegate()
{
}
QWidget *checkBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const {
QCheckBox *editor = new QCheckBox(parent);
editor->setTristate(false);
return editor;
}
void checkBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {
bool value = index.model()->data(index, Qt::EditRole).toBool();
QCheckBox *locEdit = static_cast<QCheckBox*>(editor);
locEdit->setChecked(value);
}
void checkBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
QCheckBox *locEdit = static_cast<QCheckBox*>(editor);
bool value = locEdit->isChecked();
model->setData(index, value, Qt::EditRole);
}
void checkBoxDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const {
editor->setGeometry(option.rect);
}
void checkBoxDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const {
QPalette::ColorGroup cg;
if (option.state & QStyle::State_Enabled) {
cg = (option.state & QStyle::State_Active) ? QPalette::Normal : QPalette::Inactive;
}
else
cg = QPalette::Disabled;
if (option.state & QStyle::State_Selected)
painter->fillRect(option.rect, option.palette.color(cg, QPalette::Highlight));
//if (! (parentView->editTriggers() > QAbstractItemView::NoEditTriggers && option.state & QStyle::State_Selected) )
drawCheck(painter, option, option.rect, index.data().toBool() ? Qt::Checked : Qt::Unchecked);
drawFocus(painter, option, option.rect);
}
//QSize checkBoxDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const {
// return QItemDelegate::sizeHint ( option, index );
//}
delegete绑定到我视图中的一行
checkBoxDelegate* cBD = new checkBoxDelegate(ui.personalData);
ui.personalData->setItemDelegateForRow(4, cBD);
它“有点”有效,复选框出现 - 居中:
但是当我编辑那个单元格时,createEditor(...)返回的控件被绘制在原始复选框旁边:
,
我通过添加这一行实现了我想要的目标:
if (! (parentView->editTriggers() > QAbstractItemView::NoEditTriggers && option.state & QStyle::State_Selected) ) //this one
drawCheck(painter, option, option.rect, index.data().toBool() ? Qt::Checked : Qt::Unchecked);
在paint(...)方法中。
我最终得到了类似的东西:
if (! (option.state & QStyle::State_Selected) || option.state & QStyle::State_HasFocus)
drawCheck(painter, option, option.rect, index.data().toBool() ? Qt::Checked : Qt::Unchecked);
可能看起来很奇怪,但我无法做得更好。看来,Qt在这段代码中表现得有些奇怪。选择表格单元格(不在编辑模式下)时,它具有option.state = State( "Active | Enabled | HasFocus | Selected" )
。在编辑模式下,它有State( "Enabled | Selected" )
。为什么不再“活跃”?为何不再使用HasFocus?好的,焦点可能会传递给QCheckBox。我希望,有QStyle :: State_Editing状态 - 但它没有
我仍然不确定这是否是最佳方式?