Qt: интерактивные кнопки на каждой строке, нарисованные с помощью QAbstractItemDelegate - PullRequest
7 голосов
/ 29 марта 2011

Я хотел бы нарисовать «кликабельные» значки (или кнопки) в каждой строке QListView. Я использую свой собственный собственный производный класс «QAbstractItemDelegate» для рисования.Эти кнопки могут меняться в зависимости от пользовательского статуса строки (у меня есть доступ к базовой структуре данных во время рисования).

Как лучше всего подойти к этому?

1 Ответ

6 голосов
/ 29 марта 2011

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Возможно, это не лучший способ, но здесь у вас есть полный контроль. Мы сочли необходимым сделать это с помощью флажков рисования.

Вы можете наследовать от QStyledItemDelegate (или QAbstractItemDelegate может работать .. не пробовал) и переопределять методы paint и editorEvent. Вы используете QStyle::drawControl() (после установки соответствующих параметров стиля), чтобы нарисовать элемент управления в paint, а затем вручную проверить наличие нажатия мыши в editorEvent и что-то с ним сделать. Если память мне не изменяет, этот код был в значительной степени вдохновлен ( кашель , скопирован, кашель , кашель ) от просмотра исходного кода Qt для 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...