Qt Model-View 模型视图

总体思路:

用Xml记录寄存器地址信息,解析xml后在QtableView中显示出来;

QtableView使用模型视图,自定义模型,设置代理

 

.pro文件

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    RegisterItem.cpp \
    RegisterMapWdgt.cpp \
    RegisterTableModel.cpp \
    main.cpp \
    MainWindow.cpp

HEADERS += \
    MainWindow.h \
    RegisterItem.h \
    RegisterMapWdgt.h \
    RegisterTableModel.h

FORMS += \
    MainWindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

MainWindow.h

#pragma once

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class RegisterMapWdgt;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();


private:
    Ui::MainWindow *ui;

    RegisterMapWdgt *m_pRegisterMapWdgt = nullptr;
};

MainWindow.cpp

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "RegisterMapWdgt.h"

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

    m_pRegisterMapWdgt = new RegisterMapWdgt(this);
    this->setCentralWidget(m_pRegisterMapWdgt);
}

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

RegisterItem.h

#pragma once


#include <QVariant>
#include <QVector>

class RegisterItem
{
public:
    typedef QMap<int,QVariant> Data;
    RegisterItem();

    int columnCount() const;

    QVariant data(int column, int role) const;
    bool setData(int column, const QVariant& value, int role = Qt::DisplayRole);

private:
    QVector<Data>   mColumns;
};

inline int RegisterItem::columnCount() const {
    return mColumns.size();
}

RegisterItem.cpp

#include "RegisterItem.h"

RegisterItem::RegisterItem()
{

}


QVariant RegisterItem::data(int column, int role) const
{
    Q_ASSERT(column >= 0 && column < columnCount());

    return mColumns[column][role];
}

bool RegisterItem::setData(int column, const QVariant& value, int role)
{
#if 1
    if(column < 0)
        return false;

    while (columnCount() <= column) {
        mColumns << Data();
    }

    switch (role)
    {
        case Qt::DisplayRole:
        case Qt::EditRole:
            mColumns[column][Qt::DisplayRole] = value;
            mColumns[column][Qt::EditRole] = value;
            return true;
    }

    mColumns[column][role] = value;
    return true;
#endif
}

RegisterTableModel.h

#pragma once

#include <QAbstractTableModel>
#include "RegisterItem.h"

class RegisterTableModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    RegisterTableModel();

    enum Columns { RegisterName , Address , Default, Size, Value };

public: // QAbstractItemModel interface
    int rowCount(const QModelIndex& parent) const;
    int columnCount(const QModelIndex& parent) const;
    Qt::ItemFlags flags(const QModelIndex &index) const;
    QVariant data(const QModelIndex& index, int role) const;
    bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
    QVariant headerData(int section, Qt::Orientation orientation, int role) const;
    void AddElement(const RegisterItem & item);

public:
    void initModel(const QVector<RegisterItem>& rows);

private:
    QVector<RegisterItem>  mRows;
};

RegisterTableModel.cpp

#include "RegisterTableModel.h"

RegisterTableModel::RegisterTableModel()
{

}

int RegisterTableModel::rowCount(const QModelIndex& parent) const
{
    Q_UNUSED(parent);
    return mRows.size();
}

int RegisterTableModel::columnCount(const QModelIndex& parent) const
{
    Q_UNUSED(parent);
    return mRows.size() ? mRows[0].columnCount() : 0;
}

QVariant RegisterTableModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    {
        switch (section)
        {
        case RegisterName:
            return "Register Name";
        case Address:
            return "Address";
        case Default:
            return "Default";
        case Size:
            return "Size";
        case Value:
            return "Value";
        }
    }
    return QAbstractTableModel::headerData(section, orientation, role);
}


QVariant RegisterTableModel::data(const QModelIndex& index, int role) const
{
    if (!index.isValid() || index.row() < 0 || index.row() >= mRows.size()) {
        return QVariant();
    }
    const int row = index.row();

    return mRows[row].data(index.column(), role);
}


bool RegisterTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid() || index.row() < 0 || index.row() >= mRows.count())
    {
        return false;
    }

    bool bResult = mRows[index.row()].setData(index.column(),value,role);
    if(!bResult)
    {
        return false;
    }

    emit dataChanged(index, index);
    return true;
}

Qt::ItemFlags RegisterTableModel::flags(const QModelIndex &index) const
{
    if (index.column() == RegisterName)
    {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable ;
    }
    else if (index.column() == Address)
    {
        return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable;
    }

    return QAbstractTableModel::flags(index);
}



void RegisterTableModel::initModel(const QVector<RegisterItem>& rows)
{
    beginResetModel();
    mRows.clear();
    mRows = rows;
    endResetModel();
}

void RegisterTableModel::AddElement(const RegisterItem & item)
{
    const int count = mRows.size();
    beginInsertRows(QModelIndex(), count, count);
    mRows.append(item);
    endInsertRows();
}

RegisterMapWdgt.h

#pragma once
#include <QWidget>


class QPushButton;
class RegisterTableModel;
class QSortFilterProxyModel;
class QTableView;

class RegisterMapWdgt :public QWidget
{
public:
    explicit RegisterMapWdgt(QWidget *parent = nullptr);
    ~RegisterMapWdgt();

private:
    RegisterTableModel      *m_pRegisterTableModel = nullptr;
    QSortFilterProxyModel   *m_pSortFilterModel =  nullptr;

    QPushButton *m_pCreatBtn = nullptr;
    QTableView *m_pRegistMapTableView = nullptr;

private:
    void InitCtr(void);
    void CreateRegisterItems(int count);
    bool OnParseRegsXml(const QString &filePath);
};

 

RegisterMapWdgt.cpp

#include "RegisterMapWdgt.h"
#include "qpushbutton.h"
#include "qtableview.h"
#include <QSortFilterProxyModel>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QDebug>
#include <QXmlStreamReader>
#include <QFile>


#include "RegisterTableModel.h"


RegisterMapWdgt::RegisterMapWdgt(QWidget *parent): QWidget(parent)
{
    InitCtr();
}

RegisterMapWdgt::~RegisterMapWdgt()
{
    delete m_pRegisterTableModel;
    delete m_pSortFilterModel;
    delete m_pRegistMapTableView;
}

void RegisterMapWdgt::InitCtr(void)
{

    m_pRegisterTableModel =  new  RegisterTableModel();
    m_pSortFilterModel =  new QSortFilterProxyModel();
    m_pCreatBtn = new QPushButton(tr("Creat"),this);
    m_pRegistMapTableView = new QTableView(this);

    m_pSortFilterModel->setSourceModel(m_pRegisterTableModel);
    m_pRegistMapTableView->setModel(m_pSortFilterModel);
//    m_pRegistMapTableView->setModel(m_pRegisterTableModel);
    m_pRegistMapTableView->setSortingEnabled(true);
    m_pRegistMapTableView->setSelectionBehavior(QAbstractItemView::SelectRows);

    m_pRegisterTableModel->setHeaderData(0,Qt::Horizontal,tr("Register Name"));
    m_pRegisterTableModel->setHeaderData(1,Qt::Horizontal,tr("Address"));

    QVBoxLayout *vertlayout = new QVBoxLayout();
    vertlayout->addWidget(m_pCreatBtn);
    vertlayout->addWidget(m_pRegistMapTableView);


    setLayout(vertlayout);

//    CreateRegisterItems(20);

    QString regsFile ("../myxmlstream/Registers.xml");
    OnParseRegsXml(regsFile);


}


void RegisterMapWdgt::CreateRegisterItems(int count)
{
//    QStringList listOne = QStringLiteral("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z")
//                          .split(QLatin1Char(' '));

    char addr = 0;
    QVector<RegisterItem> rows;
    RegisterItem newRow;
    newRow.setData( 0, QStringLiteral("VERSION"));
    newRow.setData( 1, QString("%1h").arg(addr++,2,10, QLatin1Char('0')));
    newRow.setData( 2, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    newRow.setData( 3, QString("%1").arg(32,2,10, QLatin1Char('0')));
    newRow.setData( 4, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    m_pRegisterTableModel->AddElement(newRow);

    newRow.setData( 0, QStringLiteral("PKT_CTL"));
    newRow.setData( 1, QString("%1h").arg(addr++,2,10, QLatin1Char('0')));
    newRow.setData( 2, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    newRow.setData( 4, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    m_pRegisterTableModel->AddElement(newRow);


    newRow.setData( 0, QStringLiteral("PLL_CTL"));
    newRow.setData( 1, QString("%1h").arg(addr++,2,10, QLatin1Char('0')));
    newRow.setData( 2, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    newRow.setData( 4, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    m_pRegisterTableModel->AddElement(newRow);

    newRow.setData( 0, QStringLiteral("LVDS_CTL"));
    newRow.setData( 1, QString("%1h").arg(addr++,2,10, QLatin1Char('0')));
    newRow.setData( 2, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    newRow.setData( 4, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    m_pRegisterTableModel->AddElement(newRow);

    newRow.setData( 0, QStringLiteral("LVDS_DAT"));
    newRow.setData( 1, QString("%1h").arg(addr++,2,10, QLatin1Char('0')));
    newRow.setData( 2, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    newRow.setData( 4, QString("0x%1").arg(addr,4,16, QLatin1Char('0')));
    m_pRegisterTableModel->AddElement(newRow);

}

bool RegisterMapWdgt::OnParseRegsXml(const QString &filePath)
{
    QFile file(filePath);
    if (!file.open(QFile::ReadOnly | QFile::Text))
    {
        qDebug()<<"Error: cannot open file";
        return 1;
    }

    QXmlStreamReader reader;

    // 设置文件,这时会将流设置为初始状态
    reader.setDevice(&file);

    RegisterItem newRow;

    // 如果没有读到文档结尾,而且没有出现错误
    while (!reader.atEnd()) {
        // 读取下一个记号,它返回记号的类型
        QXmlStreamReader::TokenType type = reader.readNext();

        // 下面便根据记号的类型来进行不同的输出
        if (type == QXmlStreamReader::StartDocument)
            qDebug() << reader.documentEncoding() << reader.documentVersion();
        if (type == QXmlStreamReader::StartElement) {
            qDebug() << "<" << reader.name() << ">";
            if (reader.attributes().hasAttribute("id"))
                qDebug() << reader.attributes().value("id");

            if(reader.name() == "Reg_Name")
            {
                newRow.setData( 0, reader.readElementText());
            }else if(reader.name() == "Address")
            {
                 newRow.setData( 1,reader.readElementText());
            }else if(reader.name() == "Default_Value")
            {
                 newRow.setData( 2,reader.readElementText());
            }else if(reader.name() == "Size")
            {
                 newRow.setData( 3,reader.readElementText());
            }else if(reader.name() == "Value")
            {
                 newRow.setData( 4,reader.readElementText());
            }


        }
        if (type == QXmlStreamReader::EndElement)
        {
            qDebug() << "</" << reader.name() << ">";
            m_pRegisterTableModel->AddElement(newRow);
        }

        if (type == QXmlStreamReader::Characters && !reader.isWhitespace())
        {
            qDebug() << "text"<<reader.text();
        }
    }

    // 如果读取过程中出现错误,那么输出错误信息
    if (reader.hasError()) {
        qDebug() << "error: " << reader.errorString();
    }

    file.close();
}



 

下载地址:https://download.csdn.net/download/u010505080/18584055

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值