带有小部件和文本的 QStandardItemModel 标头
Posted
技术标签:
【中文标题】带有小部件和文本的 QStandardItemModel 标头【英文标题】:QStandardItemModel header with widget and text 【发布时间】:2013-12-26 22:32:21 【问题描述】:我需要使用带有文本的复选框,例如“检查所有”:
在 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 的类,但我不知道这是否有助于解决我的问题。我想问是否有一种简单的方法可以实现这一目标?
问候
【问题讨论】:
不为标头工作到底是什么意思?你在视觉上看到了什么?您能否解释一下和/或附上屏幕截图?您能否发布一个独立的示例来重现该问题?请参考 sscce.org。 对不起。首先,我使用的是 qt 5.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();
不会工作。有人可能知道为什么会发生这种情况和/或如何解决这个问题的答案? 谢谢回答
【讨论】:
【参考方案2】:Qt 模型不支持标题的项目标志。在用作标题的项目上设置项目标志无效。 QHeaderView 不支持绘制复选框。恐怕继承 QHeaderView 是最简单的方法。
我写了一个基于this FAQ page如何实现的示例。此类假定您使用 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();
【讨论】:
我正在为我的程序做另一件事,但我已经回到了这个问题。使用您的代码而不做任何更改后,标题是不可见的。以上是关于带有小部件和文本的 QStandardItemModel 标头的主要内容,如果未能解决你的问题,请参考以下文章
将带有小部件和文本的行附加到 QStandardItemModel
是否有带有文本框和 2 个旋钮的默认 Android 视图小部件?