QTableView(QAbstractTableModell)添加多选框

时间:2024-03-14 18:57:33

1,界面:

QTableView(QAbstractTableModell)添加多选框

2,代码结构:

QTableView(QAbstractTableModell)添加多选框

3,tablemodel.h

/* @brief 表模型类
 *
 * 通过继承QAbstractTableModel实现表格的MVC模型
 *
 * @author zhaoyong
 */


#ifndef TABLEMODEL_H
#define TABLEMODEL_H

#include <QAbstractTableModel>
#include <QTableView>
enum EN_USERROLE_TYPE
{
    EN_USERROLE_DATATYPE = 1,   //数据类型
    EN_USERROLE_COLUMNNAME = 2, //列名
    //    EN_USERROLE_SUBSYSTEM = 3,//所属应用
};

class TableModel : public QAbstractTableModel
{
    Q_OBJECT

public:
    explicit TableModel( QObject* parent = nullptr );

    void setColumnTitle( const QStringList& listTitle );
    QStringList getColumnTitle();
    void setDelegateType( const QStringList& listDelegateType );

    void insertRow( const QStringList list );
    void removeRow( const int& row );
    void clear();

    QString getDelegateType( const int nColumn );

    const QList<QStringList>& getModelData();
    const QStringList& getModifyData();
    void clearModifyData();

    // Header:
    QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override;
    int rowCount( const QModelIndex& parent = QModelIndex() ) const override;
    int columnCount( const QModelIndex& parent = QModelIndex() ) const override;
    QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override;
    bool setData( const QModelIndex& index, const QVariant& value, int role = Qt::EditRole );
    virtual Qt::ItemFlags flags( const QModelIndex& index ) const;

    // 更新表格数据
    void updateData(QList<QStringList> recordList);

public:
    QTableView* m_pTableView;

private:
    QStringList m_header;           //标题头
    QStringList m_dataType;         //数据类型
    QList<QStringList> m_data;      //数据内容,二维结构
    QStringList m_listModify;       //记录已修改的行和列,格式:row,col
};

#endif // TABLEMODEL_H

4,tablemodel.cpp

#include "tablemodel.h"
#include <QDebug>

#define CHECK_BOX_COLUMN 0

TableModel::TableModel( QObject* parent )
    : QAbstractTableModel( parent )
{
}

void TableModel::setColumnTitle( const QStringList& listTitle )
{
    m_header = listTitle;
}

QStringList TableModel::getColumnTitle()
{
    return m_header;
}

void TableModel::setDelegateType( const QStringList& listDelegateType )
{
    m_dataType = listDelegateType;
}

void TableModel::insertRow( const QStringList list )
{
//    if ( list.count() != m_header.count() )
//    {
//        return;
//    }
    beginResetModel();
    m_data.append( list );
    endResetModel();
}

void TableModel::removeRow( const int& row )
{
    beginResetModel();
    m_data.takeAt( row );
    endResetModel();
}

void TableModel::clear()
{
    beginResetModel();
    m_data.clear();
    endResetModel();
}

const QList<QStringList>& TableModel::getModelData()
{
    return m_data;
}

const QStringList& TableModel::getModifyData()
{
    return m_listModify;
}

void TableModel::clearModifyData()
{
    m_listModify.clear();
}

QString TableModel::getDelegateType( const int nColumn )
{
    if ( nColumn < 0 || nColumn >= m_dataType.count() )
        return "";

    return m_dataType.at( nColumn );
}

QVariant TableModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
    if ( Qt::DisplayRole == role && Qt::Horizontal == orientation && section < m_header.size() )
        return QVariant( m_header.at( section ) );
    else if ( Qt::DisplayRole == role && Qt::Vertical == orientation )
        return QVariant( section+1 );

    return QVariant();
}

int TableModel::rowCount( const QModelIndex& parent ) const
{
    if ( parent.isValid() )
        return 0;

    return m_data.count();
}

int TableModel::columnCount( const QModelIndex& parent ) const
{
    if ( parent.isValid() )
        return 0;

    return m_header.count();
}

// 表格项数据
QVariant TableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();
    int nRow = index.row();
    int nColumn = index.column();
    QStringList record = m_data.at(nRow);
    switch (role)
    {
    case Qt::TextColorRole:
        return QColor(Qt::black);
    case Qt::TextAlignmentRole:
        return QVariant(Qt::AlignLeft | Qt::AlignVCenter);
    case Qt::DisplayRole:
    {
        if ( nRow <= m_data.count() )
            return m_data.at( index.row() ).at( index.column() );
    }
    case Qt::EditRole:
    {
        if ( nRow <= m_data.count() )
            return m_data.at( index.row() ).at( index.column() );
    }
    case Qt::UserRole + EN_USERROLE_DATATYPE:
    {
        if ( nRow <= m_data.count() )
            return m_dataType.at( index.column() );
    }
    case Qt::UserRole + EN_USERROLE_COLUMNNAME:
    {
        if ( nRow <= m_data.count() )
            return m_header.at( index.column() );
    }
    case Qt::CheckStateRole:
    {
        if (nColumn == CHECK_BOX_COLUMN)
        {
            if(record[CHECK_BOX_COLUMN] == true)
                return Qt::Checked;
            else return Qt::Unchecked;
        }
    }
    default:
        return QVariant();
    }
    return QVariant();
}

bool TableModel::setData( const QModelIndex& index, const QVariant& value, int role )
{
    if ( !index.isValid() )
        return false;
    int nColumn = index.column();
    QStringList record = m_data.at(index.row());
    if ( Qt::EditRole == role && index.row() <= m_data.count() &&
         m_data[index.row()][index.column()] != value.toString() )
    {
        m_data[index.row()][index.column()] = value.toString();
        QString sTmp = QString::number(index.row())+","+QString::number(index.column());
        if ( !m_listModify.contains(sTmp) )
            m_listModify.append( sTmp );
    }
    else if( Qt::CheckStateRole == role )
    {
        if (nColumn == CHECK_BOX_COLUMN)
        {
            record[CHECK_BOX_COLUMN] = (value.toInt() == Qt::Checked);
            m_data.replace(index.row(), record);
            emit dataChanged(index, index);
            return true;
        }
    }

    return true;
}


Qt::ItemFlags TableModel::flags( const QModelIndex& index ) const
{
    if ( !index.isValid() )
        return Qt::NoItemFlags;

    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    if (index.column() == CHECK_BOX_COLUMN)
    {
        flags |= Qt::ItemIsUserCheckable;
        return flags;
    }

    return QAbstractTableModel::flags( index ) | Qt::ItemIsEditable;
}

void TableModel::updateData( QList<QStringList> recordList )
{
    m_data = recordList;
    beginResetModel();
    endResetModel();
}

5,widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public slots:
    void slotCheckBoxChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight );
    void slotPrintSelectRows();

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

private:
    Ui::Widget *ui;
    QVector<int> selectRows;  //保存选择的行号
};

#endif // WIDGET_H

6,widget.cpp

 

#include "widget.h"
#include "ui_widget.h"
#include "tablemodel.h"
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    QTableView *pTableView = ui->tableView;
    TableModel *pModel = new TableModel(this);
    // 设置单行选中、最后一列拉伸、表头不高亮、无边框等
    pTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    pTableView->horizontalHeader()->setStretchLastSection(true);
    pTableView->horizontalHeader()->setHighlightSections(false);
    pTableView->verticalHeader()->setVisible(false);
    pTableView->setShowGrid(false);
    pTableView->setFrameShape(QFrame::NoFrame);
    pTableView->setSelectionMode(QAbstractItemView::SingleSelection);
    pTableView->setModel(pModel);

    QStringList title;
    title << "select" << "bbb";
    pModel->setColumnTitle( title );
    // 加载数据、更新界面
    QList<QStringList> recordList;
    for (int i = 0; i < 5; ++i)
    {
        QStringList record;
        record << "";
        record << "adadfsdfsf";
        recordList.append(record);
    }
    pModel->updateData(recordList);
    connect( pModel, &TableModel::dataChanged, this, &Widget::slotCheckBoxChanged );
    connect( ui->pushButton, SIGNAL(clicked()), this, SLOT(slotPrintSelectRows() ) );
}

Widget::~Widget()
{
    delete ui;
}

void Widget::slotCheckBoxChanged( const QModelIndex &topLeft, const QModelIndex &bottomRight )
{
    int row = topLeft.row();
    if( selectRows.contains( row ) )
        selectRows.removeOne( row );
    else
        selectRows.append( row );
}

void Widget::slotPrintSelectRows()
{
    qDebug() << selectRows;
}

7,main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}