qt - QTableView中布尔列的可单击复选框

时间:2015-01-15 12:47:49

标签: c++ qt user-interface checkbox qtableview

我希望在Table视图的其中一列中有一个复选框。具体 - 在其中一行中,因为视图使用transposing proxy model。我使用QItemDelegate派生类来完成它,如文档and here中所述:

的.h

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;
};

的.cpp

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);

它“有点”有效,复选框出现 - 居中:

checkBox in normal mode

但是当我编辑那个单元格时,createEditor(...)返回的控件被绘制在原始复选框旁边:

check box in edit mode (before change)check box in edit mode (after change)

我通过添加这一行实现了我想要的目标:

    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状态 - 但它没有

我仍然不确定这是否是最佳方式?

0 个答案:

没有答案