1. 程式人生 > 其它 >Qt QTableView 表格內新增控制元件

Qt QTableView 表格內新增控制元件

目錄

Qt QTableView 表格內新增控制元件

書接上回,之前寫了怎麼在表格的表頭新增複選框,Qt QHeaderView 新增複選框_師從名劍山的部落格-CSDN部落格。這次來寫怎麼給表格內新增控制元件。

往表格裡新增控制元件主要有兩種方法,第一種是使用代理,QItemDelegate,過載其createEditor這個函式,但是這個有個缺點,就是必須雙擊進入編輯模式才能修改,第二種方式就是setIndexWidget,這個要更好。

1. 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這個函式。

具體的效果圖如下:

2. 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 );

但是這裡有一個缺點,如果直接插入進去,會出現沒辦法控制這個控制元件的位置,這個控制元件預設在最左邊,如下圖:

3. 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);

效果圖如下: