分享

Qt QTableView 表格内添加控件

 myallmy 2022-10-11 发布于北京

1|0Qt QTableView 表格内添加控件

往表格里添加控件主要有两种方法,第一种是使用代理,QItemDelegate,重载其createEditor这个函数,但是这个有个缺点,就是必须双击进入编辑模式才能修改,第二种方式就是setIndexWidget,这个要更好。

1|11. QItemDelegate

第一种方式是使用代理的方式,重载createEditor。之前一直知道QTableView有一种代理的方式,但是觉得这种方式很复杂,于是就基本没有用这个方法,最近刚好用到,就去了解了一下。

对于createEditor,我的理解是创建一个对表格的编辑,所以就需要双击之后才会显示,同样。这里参考QT的文档里对于这种方法的解释,同时在QT的示例spin box delegate中,有比较详尽的解释。

截取其中的一部分,对于createEditorsetEditorDatasetModelData这几个函数的用处。

在这里插入图片描述

createEditor: 创建一个编辑器小部件,并将其直接显示在项目的顶部。

setEditorData: 用来自model里的数据来填充editor。

setModelData: 用editor的数据来填充model。

代码如下:

delegate.h

#ifndef DELEGATE_H #define DELEGATE_H #include <QItemDelegate> #include <QCheckBox> #include <QApplication> class Delegate : public QItemDelegate { public: Delegate(QObject* parent = nullptr); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const; // void setEditorData(QWidget *editor, const QModelIndex &index) const; // void setModelData(QWidget *editor, QAbstractItemModel *model, // const QModelIndex &index) const; }; #endif // DELEGATE_H

delegate.cpp

#include "delegate.h" Delegate::Delegate(QObject *parent) { } void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QItemDelegate::paint(painter, option, index); } QSize Delegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QItemDelegate::sizeHint(option, index); } QWidget *Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { if (index.isValid() && index.column() == 0) { QCheckBox* checkBox = new QCheckBox(parent); checkBox->installEventFilter(const_cast<Delegate*> (this)); return checkBox; } else { return QItemDelegate::createEditor(parent, option, index); } }

由于此处添加的是一个复选框,所以没有重载setEditorDatasetModelData这两个函数,只是重载了createEditor这个函数。

具体的效果图如下:

在这里插入图片描述

1|22. setIndexWidget

第二种方式是使用这个API : void QAbstractItemView::setIndexWidget(const QModelIndex &index, QWidget *widget)

index代表单元格所在的下标,widget代表你需要添加的窗口。

代码如下:

tableviewModel = new QStandardItemModel; ui->tableView->setModel(tableviewModel); QStringList headerList; headerList<<"姓名"<<"性别"<<"年龄"; tableviewModel->setHorizontalHeaderLabels(headerList); tableviewModel->setItem(0,1,new QStandardItem("张三")); tableviewModel->setItem(1,1,new QStandardItem("李四")); tableviewModel->setItem(2,1,new QStandardItem("王二")); QStandardItem* item = new QStandardItem(); QCheckBox *checkBox = new QCheckBox(); tableviewModel->setItem(0, 0, item); ui->tableView->setIndexWidget(tableviewModel->index(0, 0), checkBox );

但是这里有一个缺点,如果直接插入进去,会出现没办法控制这个控件的位置,这个控件默认在最左边,如下图:

在这里插入图片描述

1|33. setIndexWidget + setLayout

根据上面出现的情况,可以先创建一个widget,然后再创建一个布局,在把你需要添加的控件加到这个布局里去,然后再根据你的需求来布局。

代码如下:

tableviewModel = new QStandardItemModel; ui->tableView->setModel(tableviewModel); QStringList headerList; headerList<<"姓名"<<"性别"<<"年龄"; tableviewModel->setHorizontalHeaderLabels(headerList); tableviewModel->setItem(0,1,new QStandardItem("张三")); tableviewModel->setItem(1,1,new QStandardItem("李四")); tableviewModel->setItem(2,1,new QStandardItem("王二")); QStandardItem* item = new QStandardItem(); QWidget* checkWidget = new QWidget(); QHBoxLayout* hLayout = new QHBoxLayout; QCheckBox *checkBox = new QCheckBox(checkWidget); hLayout->setContentsMargins(10, 0, 0, 0); hLayout->addWidget(checkBox); checkWidget->setLayout(hLayout); tableviewModel->setItem(0, 0, item); ui->tableView->setIndexWidget(tableviewModel->index(0, 0), checkWidget);

效果图如下:
在这里插入图片描述


__EOF__


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多