Qt QTableView 如何只有一个复选框列 [英] Qt QTableView how to have a checkbox only column

查看:36
本文介绍了Qt QTableView 如何只有一个复选框列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在 Qt 4.6.3 中使用 QTableView,并且需要一个在每个单元格中只有一个复选框的列.我们使用 QAbstractTableModel 的自定义子类作为 QTableView 的模型.现在,我们通过设置 Qt::ItemIsUserCheckable 标志有一个复选框.但是我们不知道如何去掉复选框旁边的空白文本框!

We are using a QTableView with Qt 4.6.3, and need a column that only has a checkbox in each cell. We're using a custom subclass of QAbstractTableModel as the model for the QTableView. Right now, we have a checkbox by setting the Qt::ItemIsUserCheckable flag. But we can't figure out how to get rid of the blank textbox next to the checkbox!

我们怎样才能让列只有有一个复选框,没有别的?

How can we make the column only have a checkbox, nothing else?

推荐答案

这里有一个解决方案.为了使其正常工作,您的列应该设置 Qt::ItemIsEditableQt::ItemIsUserCheckable 标志.这从 Qt::DisplayRole 读取布尔值并调用 setData()Qt::EditRole(即 not Qt::CheckStateRole.)

Here is a solution. For this to work properly, your column should not have the Qt::ItemIsEditable or Qt::ItemIsUserCheckable flags set. This reads the boolean values from Qt::DisplayRole and calls setData() with Qt::EditRole (i.e. not Qt::CheckStateRole.)

#include "check_box_delegate.h"

#include <QtGui/QApplication>
#include <QtGui/QMouseEvent>

static QRect CheckBoxRect(const QStyleOptionViewItem &view_item_style_options) {
  QStyleOptionButton check_box_style_option;
  QRect check_box_rect = QApplication::style()->subElementRect(
      QStyle::SE_CheckBoxIndicator,
      &check_box_style_option);
  QPoint check_box_point(view_item_style_options.rect.x() +
                         view_item_style_options.rect.width() / 2 -
                         check_box_rect.width() / 2,
                         view_item_style_options.rect.y() +
                         view_item_style_options.rect.height() / 2 -
                         check_box_rect.height() / 2);
  return QRect(check_box_point, check_box_rect.size());
}

CheckBoxDelegate::CheckBoxDelegate(QObject *parent)
  : QStyledItemDelegate(parent) {
}

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

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

// This is essentially copied from QStyledItemEditor, except that we
// have to determine our own "hot zone" for the mouse click.
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 false;
    }
    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 = index.model()->data(index, Qt::DisplayRole).toBool();
  return model->setData(index, !checked, Qt::EditRole);
}

这篇关于Qt QTableView 如何只有一个复选框列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆