.h
#ifndef TABLEDATA_H
#define TABLEDATA_H
#include
class TableData
{
public:
TableData();
QStringList getHeadData() const;
void setHeadData(const QStringList &headData);
QList getDatas() const;
void setDatas(const QList &datas);
void updataData(int row,int column,const QString &data);
void addRowData(const QStringList &rowData);
void deleteRowData(int row);
static TableData *getInstance();
private:
QStringList m_headData;
QList m_datas;
};
#endif // TABLEDATA_H
.cpp
#include "TableData.h"
#include
TableData::TableData()
{
QStringList head;head<<"1"<<"2"<<"3"<<"4"<<"5";
m_headData = head;
QStringList row1;row1<<"0"<<"5"<<"4"<<"3";
QStringList row2;row2<<"0"<<"1"<<"1"<<"3";
m_datas.append(row1);
m_datas.append(row2);
}
QStringList TableData::getHeadData() const
{
return m_headData;
}
void TableData::setHeadData(const QStringList &headData)
{
m_headData = headData;
}
QList TableData::getDatas() const
{
return m_datas;
}
void TableData::setDatas(const QList &datas)
{
m_datas = datas;
}
void TableData::updataData(int row, int column, const QString &data)
{
m_datas[row][column] = data;
}
void TableData::addRowData(const QStringList &rowData)
{
m_datas.append(rowData);
}
void TableData::deleteRowData(int row)
{
m_datas.removeAt(row);
}
TableData *TableData::getInstance()
{
static TableData tableData;
return &tableData;
}
.h
#ifndef TABLEVIEWMODEL_H
#define TABLEVIEWMODEL_H
#include
class TableData;
class TableViewModel :public QAbstractTableModel
{
Q_OBJECT
public:
TableViewModel(QObject *parent = nullptr);
void refeshModel();
void removeRow(int row);
//数据行数
int getRowCount();
//自定义单元格列数
int getCellWindowColumn();
// QAbstractItemModel interface
public:
virtual int rowCount(const QModelIndex &parent) const override;
virtual int columnCount(const QModelIndex &parent) const override;
//单元格中的数据
virtual QVariant data(const QModelIndex &index, int role) const override;
//设置数据源的数据
virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
signals:
//提示别人输入内容有误
void signal_filterText(const QModelIndex &index);
private:
TableData *m_pTableData = nullptr;
};
#endif // TABLEVIEWMODEL_H
.cpp
#include "TableViewModel.h"
#include "TableData.h"
#include
#include
#include
TableViewModel::TableViewModel(QObject *parent):QAbstractTableModel(parent)
{
m_pTableData = TableData::getInstance();
}
int TableViewModel::rowCount(const QModelIndex &parent) const
{
if (parent.isValid())
{
return 0;
}
else
{
return m_pTableData->getDatas().size(); //显示数据的大小
}
}
int TableViewModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
{
return 0;
}
else
{
return m_pTableData->getHeadData().size(); //表头的大小
}
}
QVariant TableViewModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
{
return QVariant();
}
if (role == Qt::DisplayRole)
{
if(m_pTableData->getDatas().at(index.row()).size()==index.column())
{
return QVariant();
}
return m_pTableData->getDatas().at(index.row()).at(index.column()); //单元格中数据
}
if (role == Qt::TextAlignmentRole)
{ //对其方式
return Qt::AlignCenter; //对齐格式为居中
}
return QVariant();
}
bool TableViewModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role != Qt::EditRole)
{
return false;
}
if(!index.isValid())
{
return false;
}
if(m_pTableData->getDatas().at(index.row()).size()==index.column())
{
return false;
}
if(!value.toString().contains(QRegExp("[0-9]+$")))
{
emit signal_filterText(index);
return false;
}
m_pTableData->updataData(index.row(),index.column(),value.toString());
emit dataChanged(index, index);
return true;
}
QVariant TableViewModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal)
{ //水平表头
if (role == Qt::DisplayRole)
{ //角色为显示
return m_pTableData->getHeadData().at(section); //返回指定位置表头
}
}
return QAbstractTableModel::headerData(section, orientation, role);
}
Qt::ItemFlags TableViewModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
{
return 0;
}
if(index.column()==(m_pTableData->getHeadData().size()-1))
{
//最后一列不可编辑
return Qt::ItemIsEnabled;
}
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
}
void TableViewModel::refeshModel()
{
beginResetModel();//刷新表格
endResetModel();
}
void TableViewModel::removeRow(int row)
{
m_pTableData->deleteRowData(row);
refeshModel();
}
int TableViewModel::getRowCount()
{
return m_pTableData->getDatas().size();
}
int TableViewModel::getCellWindowColumn()
{
return m_pTableData->getHeadData().size()-1;
}
自定义控件
控件的宽度也固定
然后完善这个自定义控件类
.h
#ifndef TABLEVIEWCELL_H
#define TABLEVIEWCELL_H
#include
#include
namespace Ui {
class TableViewCell;
}
class TableViewCell : public QWidget
{
Q_OBJECT
public:
explicit TableViewCell(QWidget *parent = 0);
~TableViewCell();
//设置控件是哪一行
void setRow(int row);
int row() const;
signals:
//点击按钮发出信号
void deleteData();
private:
Ui::TableViewCell *ui;
int m_row;
};
#endif // TABLEVIEWCELL_H
.cpp
#include "TableViewCell.h"
#include "ui_TableViewCell.h"
TableViewCell::TableViewCell(QWidget *parent) :
QWidget(parent),
ui(new Ui::TableViewCell)
{
ui->setupUi(this);
ui->pushButton_edit->setStyleSheet("#pushButton_edit{border-image:url(:/image/image/edit.png);"
"width:16px;height:16px;"
"border-radius: 0px;"
"padding: 0px;"
"background-color:transparent;}"
"#pushButton_edit:hover{border-image:url(:/image/image/editHover.png);}");
ui->pushButton_delete->setStyleSheet("#pushButton_delete{border-image:url(:/image/image/delete.png);"
"width:16px;height:16px;"
"border-radius: 0px;"
"padding: 0px;"
"background-color:transparent;}"
"#pushButton_delete:hover{border-image:url(:/image/image/deleteHover.png);}");
connect(ui->pushButton_delete,&QPushButton::clicked,this,&TableViewCell::deleteData);
}
TableViewCell::~TableViewCell()
{
delete ui;
}
int TableViewCell::row() const
{
return m_row;
}
void TableViewCell::setRow(int row)
{
m_row = row;
}
tableview.h
#ifndef TABLEVIEW_H
#define TABLEVIEW_H
#include
#include
#include
namespace Ui {
class Tableview;
}
class TableViewModel;
class TableViewCell;
class Tableview : public QWidget
{
Q_OBJECT
public:
explicit Tableview(QWidget *parent = 0);
~Tableview();
//每次刷新行重新填充自定义控件,就和刷新填充数据一样
void fillCustomCell();
private:
Ui::Tableview *ui;
TableViewModel *m_tableModel;
QListm_cellList;
};
#endif // TABLEVIEW_H
tableview.cpp
#include "Tableview.h"
#include "ui_Tableview.h"
#include
#include
#include
#include
#include "TableViewModel.h"
#include
#include "TableData.h"
#include "TableViewCell.h"
#include
Tableview::Tableview(QWidget *parent) :
QWidget(parent),
ui(new Ui::Tableview)
{
ui->setupUi(this);
//铺满整个窗口
ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView::section {"
"color: black;border: 1px solid #6c6c6c;}");
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
ui->tableView->verticalHeader()->setVisible(false);
m_tableModel = new TableViewModel(ui->tableView);
ui->tableView->setModel(m_tableModel);
fillCustomCell();
}
Tableview::~Tableview()
{
qDeleteAll(m_cellList);
m_cellList.clear();
delete ui;
}
void Tableview::fillCustomCell()
{
qDeleteAll(m_cellList);
m_cellList.clear();
for(int i = 0;igetRowCount();i++)
{
TableViewCell *cellWindow = new TableViewCell;
connect(cellWindow,&TableViewCell::deleteData,[=](){
m_tableModel->removeRow(cellWindow->row());
fillCustomCell();
});
cellWindow->setRow(i);
m_cellList.append(cellWindow);
ui->tableView->setIndexWidget(m_tableModel->index(i,m_tableModel->getCellWindowColumn()),cellWindow);
}
}
经过尝试发现tableView->setIndexWidget这种方式的效果最好,因为我们没有点击单元格也响应了事件,而使用delegate的方式,只有点击单元格才会响应事件。
this->setEditTriggers(QAbstractItemView::NoEditTriggers);//禁用双击编辑
connect(it.value(),&QAction::triggered,[&]{
QModelIndex index=this->currentIndex();
if(!index.isValid())
return ;
this->edit(index);
});