Qt:使用QAbstractItemDelegate自定义绘制的每一行上的可点击"按钮"

Jas*_*enX 7 qt

我想在QListView的每一行上绘制'可点击'图标(或按钮)我正在使用我自己的自定义"QAbstractItemDelegate"派生类进行绘制.这些按钮可能会随着行的自定义状态而改变(我可以在绘制期间访问底层数据结构).

什么是最好的方法来解决这个问题?

Dav*_*eer 6

免责声明:这可能不是最好的方式,但这里有一种完全控制的方式.我们发现有必要使用绘制复选框来执行此操作.

你可以继承QStyledItemDelegate(或者QAbstractItemDelegate可以工作......没有尝试过)并重新实现painteditorEvent方法.您可以使用QStyle::drawControl()(在设置适当的样式选项之后)将控件绘制到其中paint,然后手动测试鼠标中的鼠标editorEvent并对其执行操作.如果记忆正确地为我服务,这段代码很大程度上受到启发(咳嗽,复制,咳嗽,咳嗽)的查看QStyledItemDelegate.

void CheckBoxDelegate::paint(QPainter *painter,
                             const QStyleOptionViewItem &option,
                             const QModelIndex &index) const {
  bool checked = index.model()->data(index, Qt::DisplayRole).toBool();

  if (option.state & QStyle::State_Selected) {
    painter->setPen(QPen(Qt::NoPen));
    if (option.state & QStyle::State_Active) {
      painter->setBrush(QBrush(QPalette().highlight()));
    }
    else {
      painter->setBrush(QBrush(QPalette().color(QPalette::Inactive,
                                                QPalette::Highlight)));
    }
    painter->drawRect(option.rect);
  }

 QStyleOptionButton check_box_style_option;
  check_box_style_option.state |= QStyle::State_Enabled;
  if (checked) {
    check_box_style_option.state |= QStyle::State_On;
  } else {
    check_box_style_option.state |= QStyle::State_Off;
  }
  check_box_style_option.rect = CheckBoxRect(option);

  QApplication::style()->drawControl(QStyle::CE_CheckBox,
                                     &check_box_style_option,
                                     painter);
}

bool CheckBoxDelegate::editorEvent(QEvent *event,
                                   QAbstractItemModel *model,
                                   const QStyleOptionViewItem &option,
                                   const QModelIndex &index) {
  if ((event->type() == QEvent::MouseButtonRelease) ||
      (event->type() == QEvent::MouseButtonDblClick)) {
    QMouseEvent *mouse_event = static_cast<QMouseEvent*>(event);
    if (mouse_event->button() != Qt::LeftButton ||
        !CheckBoxRect(option).contains(mouse_event->pos())) {
      return true;
    }
    if (event->type() == QEvent::MouseButtonDblClick) {
      return true;
    }
  } else if (event->type() == QEvent::KeyPress) {
    if (static_cast<QKeyEvent*>(event)->key() != Qt::Key_Space &&
        static_cast<QKeyEvent*>(event)->key() != Qt::Key_Select) {
      return false;
    }
  } else {
    return false;
  }

  bool checked = model->data(index, Qt::DisplayRole).toBool();
  return model->setData(index, !checked, Qt::EditRole);
}
Run Code Online (Sandbox Code Playgroud)