1,界面:
2,代码结构:
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();
}