1

我需要使用带有文本的复选框,例如“全选”:

在此处输入图像描述

在 QStandardItemModel 的标头中。我试过这样

QStandardItem* item0 = new QStandardItem("some text");
item0->setCheckable(true);
item0->setCheckState(Qt::Checked);
item0->setText("some text");

_model->setHorizontalHeaderItem(1, item0);

这种方式仅适用于项目而不适用于标题,我的意思是如果我使用项目

_model->setItem(new QStandardItem(some_item);

我听说要编写自己的继承 QHeaderView 的类,但我不知道这是否有助于解决我的问题。我想问是否有一种简单的方法可以实现这一目标?

问候

4

2 回答 2

1


我做了这样的事情:

QStandardItemModel *model = new QStandardItemModel(this);

ui->tableView->setModel(model);

QtCheckHeaderView *header = new QtCheckHeaderView(Qt::Horizontal, ui->tableView);


QtCheckHeaderView *vheader = new QtCheckHeaderView(Qt::Vertical, ui->tableView);

ui->tableView->setHorizontalHeader(header);
ui->tableView->setVerticalHeader(vheader);

QStandardItem *root = model->invisibleRootItem();
QList<QList<QStandardItem *> > items;
for (int i = 0; i < 10; ++i)
{
    QList<QStandardItem *> res;
    for (int j = 0; j < 1000; ++j)
    {
        res.append(new QStandardItem(QString("%1;%2").arg(j).arg(i)));
        vheader->addCheckable(j);
    }
    items.append(res);
    root->appendColumn(res);

    header->addCheckable(i);
}

这很好用。在垂直和水平标题中绘制带有文本的复选框。但这只有在我将此代码放入 MainWindow 构造函数时才有效。如果我将此代码用于例如按钮功能,这将不起作用。数据很好,但标题是不可见的。

ui->tableView->repaint();

不会工作。有人可能知道为什么会发生这种情况和/或如何解决这个问题?谢谢你的回答

于 2014-01-14T19:29:28.213 回答
0

Qt 模型不支持标题的项目标志。在用作标题的项目上设置项目标志无效。QHeaderView 不支持绘制复选框。恐怕继承 QHeaderView 是最简单的方法。

我写了一个例子来说明它是如何基于这个 FAQ 页面来实现的。此类假定您使用 QStandardItemModel 并使用其标题项的标志。如果有人想使用其他模型类,则需要子类化 QAbstractItemModel 并实现缺少的接口并更改 headerview 实现。

class MyHeader : public QHeaderView
{
public:
  MyHeader(Qt::Orientation orientation, QWidget * parent = 0);

protected:
  QStandardItemModel* standard_model;
  virtual void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const;
  virtual void mousePressEvent(QMouseEvent *event);
  virtual void setModel(QAbstractItemModel* model);

};

MyHeader::MyHeader(Qt::Orientation orientation, QWidget *parent) : QHeaderView(orientation, parent)
{
  standard_model = 0;
}

void MyHeader::paintSection(QPainter *painter, const QRect &rect, int logical_index) const {
  painter->save();
  QHeaderView::paintSection(painter, rect, logical_index);
  painter->restore();
  if (standard_model && orientation() == Qt::Horizontal) {
    QStandardItem* item = standard_model->horizontalHeaderItem(logical_index);
    if (item && item->isCheckable()) {
      int offset = (height() - style()->pixelMetric(QStyle::PM_IndicatorHeight))/2;
      int pos = sectionViewportPosition(logical_index);
      QStyleOptionButton option;
      option.rect = QRect(offset + pos, offset,
                          style()->pixelMetric(QStyle::PM_IndicatorWidth),
                          style()->pixelMetric(QStyle::PM_IndicatorHeight));
      if (item->checkState() == Qt::Checked) {
        option.state = QStyle::State_On;
      } else {
        option.state = QStyle::State_Off;
      }
      option.state |= QStyle::State_Enabled;
      style()->drawPrimitive(QStyle::PE_IndicatorCheckBox, &option, painter);
    }
  }
}

void MyHeader::mousePressEvent(QMouseEvent *event) {
  int offset = (height() - style()->pixelMetric(QStyle::PM_IndicatorHeight))/2;
  if (standard_model && orientation() == Qt::Horizontal) {
    for(int logical_index = 0; logical_index < count(); logical_index++) {
      int pos = sectionViewportPosition(logical_index);
      QRect rect(offset + pos, offset,
                 style()->pixelMetric(QStyle::PM_IndicatorWidth),
                 style()->pixelMetric(QStyle::PM_IndicatorHeight));
      if (rect.contains(event->pos())) {
        QStandardItem* item = standard_model->horizontalHeaderItem(logical_index);
        if (item && item->isCheckable()) {
          item->setCheckState(item->checkState() == Qt::Checked ? Qt::Unchecked : Qt::Checked);
          return;
        }
      }
    }
  }
  QHeaderView::mousePressEvent(event);
}

void MyHeader::setModel(QAbstractItemModel *model) {
  QHeaderView::setModel(model);
  standard_model = qobject_cast<QStandardItemModel*>(model);
}

//usage
QTableView  view;
QStandardItemModel model;
model.setColumnCount(5);
QStandardItem* item0 = new QStandardItem("some text");
item0->setCheckable(true);
item0->setCheckState(Qt::Checked);
item0->setText("some text");
model.setHorizontalHeaderItem(0, item0);
view.setModel(&model);
MyHeader *myHeader = new MyHeader(Qt::Horizontal, &view);
view.setHorizontalHeader(myHeader);
view.show();
于 2013-12-27T08:49:51.563 回答