QT QTableview视图数据分离QAbstractTableMod+自定义控件

.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;
}

自定义控件


image.png

控件的宽度也固定


image.png

然后完善这个自定义控件类
.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);
    }
}
1.gif

经过尝试发现tableView->setIndexWidget这种方式的效果最好,因为我们没有点击单元格也响应了事件,而使用delegate的方式,只有点击单元格才会响应事件。

   this->setEditTriggers(QAbstractItemView::NoEditTriggers);//禁用双击编辑

            connect(it.value(),&QAction::triggered,[&]{
                QModelIndex index=this->currentIndex();
                if(!index.isValid())
                    return ;
                this->edit(index);
            });

你可能感兴趣的:(QT QTableview视图数据分离QAbstractTableMod+自定义控件)