QTableView 和 QAbstractTableModel 或QStandardItemModel

1.自定义类继承QAbstractTableModel

头文件如下:

#ifndef TESTMOUDLE_H
#define TESTMOUDLE_H
#include "StructTest.h"
#include 

class TestMoudle : public QAbstractTableModel
{
public:
    TestMoudle(QStringList& list, QObject *parent = nullptr);
    ~TestMoudle();
    void AddData(StructTest test);
    void DelData(int index );
public:
    virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
    virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
public:
    QList m_list;
    QStringList m_headList;
};
#endif // TESTMOUDLE_H

源文件

#include "TestMoudle.h"

TestMoudle::TestMoudle(QStringList& list, QObject *parent )
    : QAbstractTableModel(parent), m_headList(list)
{
}

TestMoudle::~TestMoudle()
{

}


Qt::ItemFlags TestMoudle::flags(const QModelIndex &index) const
{
    Qt::ItemFlags flags = QAbstractTableModel::flags(index);
    return flags|Qt::ItemIsEditable; //需要双击编辑 添加 Qt::ItemIsEditable
}
int TestMoudle::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return m_list.size();
}
int TestMoudle::columnCount(const QModelIndex &parent ) const
{
    Q_UNUSED(parent)
    return 2;
}

bool TestMoudle::setData(const QModelIndex &index, const QVariant &value, int role )
{
    if (!index.isValid())
        return false;

    if(role == Qt::EditRole)
    {
        int iRow = index.row(), iCol = index.column();
        if( iRow >= 0 && iRow < m_list.size() )
        {
            if(iCol == 0)
            {
                m_list[iRow].ID = value.toString();
            }
            else if(iCol == 1)
            {
                m_list[iRow].name = value.toString();
            }
        }
    }

    return true;
}

QVariant TestMoudle::data(const QModelIndex &index, int role ) const
{
    if (!index.isValid())
    {
        return QVariant();
    }
    switch (role)
    {
        case Qt::DisplayRole:
        case Qt::EditRole://不添加 双击编辑 原来的内容为空了
        {
            int row = index.row();
            if(row < 0 || row > m_list.size() )
                return QVariant();
            if(index.column()==0)
                return m_list[row].ID;
            else
                return m_list[row].name;
        }
        break;
        case Qt::TextAlignmentRole:
        {
            return QVariant(Qt::AlignCenter);
        }
        break;
        default:
            return QVariant();
    }
    return QVariant();
}

QVariant TestMoudle::headerData(int section, Qt::Orientation orientation, int role ) const
{
    if (role==Qt::TextAlignmentRole)
    {
        return QVariant(Qt::AlignCenter);
        if (section==0)
        {
            return QVariant(Qt::AlignCenter);
        }
        else
        {
            return QVariant(Qt::AlignVCenter|Qt::AlignLeft);
        }
    }
    else if (role==Qt::DisplayRole)
    {
        if( orientation==Qt::Horizontal )
        {
            if(  section>=0 && section < m_headList.size() )
                return m_headList.at(section);
        }
        else
           return  QString("%1").arg(section + 1);
    }
    return QAbstractTableModel::headerData(section,orientation,role);
}


void TestMoudle::AddData(StructTest test)
{
    beginResetModel();
    m_list << test;
    endResetModel();
}

void TestMoudle::DelData(int index )
{
    beginResetModel();
    m_list.removeAt(index);
    endResetModel();
}
//mainwidow.cpp
bool InitTableWidget( QTableView *pTableView, QStringList& list, bool bStretch, QList& width, bool bVStretch, int hight)
{
    if( !bStretch && list.size() != width.size() )
        return false;

    pTableView->horizontalHeader()->setMinimumSectionSize(1);

    if( bStretch )
    {
        pTableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);//宽度自适应
        //pTableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    }
    else
    {
        for (int i=0;i< width.size();i++ ) {
            pTableView->setColumnWidth(i, width.at(i));
        }
    }
    pTableView->horizontalHeader()->setDefaultAlignment (Qt::AlignLeft | Qt::AlignVCenter);
    pTableView->setAlternatingRowColors(true);/* 行颜色交替显示 */
    if(bVStretch)
        pTableView->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    else
        pTableView->verticalHeader()->setDefaultSectionSize(hight);
    pTableView->setSelectionBehavior ( QAbstractItemView::SelectItems);
    //pTableView->setEditTriggers(QAbstractItemView::DoubleClicked);
    pTableView->verticalHeader()->setHidden( true );
    pTableView->setShowGrid(true);
    pTableView->setFocusPolicy(Qt::NoFocus);//隐藏选中虚线
    pTableView->horizontalHeader()->setHighlightSections(true);
    pTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    return true;
}


void MainWindow::InitTable()
{
    QList width;
    QStringList list;
    list << "ID" << "Name";
    m_pMoude = new TestMoudle(list);
    ui->tableView->setModel(m_pMoude);
    QAbstractItemView::EditTriggers xx = ui->tableView->editTriggers();
    InitTableWidget( ui->tableView, list, true,  width, false, 30);
    //ui->tableView->setEditTriggers(QAbstractItemView::CurrentChanged);
    //ui->tableView->setEditTriggers(QAbstractItemView::DoubleClicked);
   // connect(ui->tableView, &QTableView::doubleClicked, this, &MainWindow::slotRowDoubleClicked);
}

//添加
void MainWindow::on_pushButton_clicked()
{
    int row = m_pMoude->rowCount();
    StructTest test;
    test.ID = QString("ID %1").arg(row+1);
    test.name = QString("name %1").arg(row+1);
    m_pMoude->AddData(test);
}


//删除
void MainWindow::on_pushButton_2_clicked()
{
    QModelIndex index = ui->tableView->selectionModel()->currentIndex();
    int currentRow = index.row();
    if( currentRow < 0)
    {
        return;
    }
    m_pMoude->DelData(currentRow);
}

如下时使用得 QStandardItemModel

#include "myQStandardItemModel.h"

myQStandardItemModel::myQStandardItemModel(QStringList& list, QObject *parent )
    : QStandardItemModel(parent), m_headList(list)
{
    setColumnCount(list.size());
    setHorizontalHeaderLabels(list);
}

myQStandardItemModel::~myQStandardItemModel()
{

}


Qt::ItemFlags myQStandardItemModel::flags(const QModelIndex &index) const
{
    Qt::ItemFlags flags = QStandardItemModel::flags(index);
    return flags|Qt::ItemIsEditable; //需要双击编辑 添加 Qt::ItemIsEditable
}
int myQStandardItemModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent)
    return m_list.size();
}
int myQStandardItemModel::columnCount(const QModelIndex &parent ) const
{
    Q_UNUSED(parent)
    return m_headList.size();
}

bool myQStandardItemModel::setData(const QModelIndex &index, const QVariant &value, int role )
{
    if (!index.isValid())
        return false;

    if(role == Qt::EditRole)
    {
        int iRow = index.row(), iCol = index.column();
        if( iRow >= 0 && iRow < m_list.size() )
        {
            if(iCol == 0)
            {
                m_list[iRow].ID = value.toString();
            }
            else if(iCol == 1)
            {
                m_list[iRow].name = value.toString();
            }
        }
    }

    return true;
}

QVariant myQStandardItemModel::data(const QModelIndex &index, int role ) const
{
    if (!index.isValid())
    {
        return QVariant();
    }
    switch (role)
    {
        case Qt::DisplayRole:
        case Qt::EditRole://不添加 双击编辑 原来的内容为空了
        {
            int row = index.row();
            if(row < 0 || row > m_list.size() )
                return QVariant();
            if(index.column()==0)
                return m_list[row].ID;
            else
                return m_list[row].name;
        }
        break;
        case Qt::TextAlignmentRole:
        {
            return QVariant(Qt::AlignCenter);
        }
        break;
        default:
            return QVariant();
    }
    return QVariant();
}

QVariant myQStandardItemModel::headerData(int section, Qt::Orientation orientation, int role ) const
{
    if (role==Qt::TextAlignmentRole)
    {
        return QVariant(Qt::AlignCenter);
        if (section==0)
        {
            return QVariant(Qt::AlignCenter);
        }
        else
        {
            return QVariant(Qt::AlignVCenter|Qt::AlignLeft);
        }
    }
//    else if (role==Qt::DisplayRole)//这里不像 QAbstractTableModel 可以不添加 甚至这个方法都可以不写
//    {
//        if( orientation==Qt::Horizontal )
//        {
//            if(  section>=0 && section < m_headList.size() )
//                return m_headList.at(section);
//        }
//        else
//           return  QString("%1").arg(section + 1);
//    }
    return QStandardItemModel::headerData(section,orientation,role);
}


void myQStandardItemModel::AddData(StructTest test)
{
    beginResetModel();
    m_list << test;
    setRowCount(m_list.size());//这个必须在m_list << test之后;
    endResetModel();
}

void myQStandardItemModel::DelData(int index )
{
    beginResetModel();
    removeRow(index);//这个必须在m_list.removeAt(index);前边
    m_list.removeAt(index);
    endResetModel();
}

你可能感兴趣的:(windows,qt,c++)