zoukankan      html  css  js  c++  java
  • qml----Model/View入门(五)C++继承实现xmllistmodel

      上一节我们直接用xmlListModel读取xml文件数据,这一节我们来看怎么用C++来实现它

      首先我们自定义头文件vediolistmodel.h,代码如下:

      

    #ifndef VedioListModel_H
    #define VedioListModel_H
    
    #include <QAbstractListModel>
    class VideoListModelPrivate;
    
    class VedioListModel : public QAbstractListModel
    {
        Q_OBJECT
        Q_PROPERTY(QString source READ source WRITE setSource)//导出source属性
    public:
        VedioListModel(QObject* parent = 0);
        ~VedioListModel();
    
        int rowCount(const QModelIndex &parent) const;
        QVariant data(const QModelIndex &index, int role) const;
        QHash<int, QByteArray> roleNames() const;
        QString source();
        void setSource(const QString& filePath);
    
        Q_INVOKABLE QString errorString() const;
        Q_INVOKABLE bool hasError() const;
        Q_INVOKABLE void reload();
        Q_INVOKABLE void remove(int index);
    
    private:
        VideoListModelPrivate *m_dptr;
    };
    
    #endif // VedioListModel_H

      然后再看实现文件vediolistmodel.cpp

      

    #include "VedioListModel.h"
    #include <QXmlStreamReader>
    #include <QVector>
    #include <QDebug>
    #include <QFile>
    
    typedef QVector<QString> VideoData;
    
    class VideoListModelPrivate
    {
    public:
        VideoListModelPrivate()
            : m_bError(false)
        {
            int role = Qt::UserRole;
            m_roleNames.insert(role++, "name");
            m_roleNames.insert(role++, "date");
            m_roleNames.insert(role++, "director_tag");
            m_roleNames.insert(role++, "director");
            m_roleNames.insert(role++, "actor_tag");
            m_roleNames.insert(role++, "actor");
            m_roleNames.insert(role++, "rating_tag");
            m_roleNames.insert(role++, "rating");
            m_roleNames.insert(role++, "desc_tag");
            m_roleNames.insert(role++, "desc");
            m_roleNames.insert(role++, "img");
            m_roleNames.insert(role++, "playpage");
            m_roleNames.insert(role++, "playtimes");
        }
    
        ~VideoListModelPrivate(){clear();}
    
        void load(){
            QXmlStreamReader reader;
            QFile file(m_strXmlFile);
            if(!file.exists())
            {
                m_bError = true;
                m_strError = "file not found!";
                return;
            }
    
            if(!file.open(QFile::ReadOnly))
            {
                m_bError = true;
                m_strError = file.errorString();
                return;
            }
    
            reader.setDevice(&file);
            QStringRef elementName;
            VideoData *video;
            while(!reader.atEnd())
            {
                reader.readNext();
                if(reader.isStartElement())
                {
                    elementName = reader.name();
                    if("video" == elementName)
                    {
                        video = new VideoData();
                        QXmlStreamAttributes attrs = reader.attributes();
                        video->append(attrs.value("name").toString());
                        video->append(attrs.value("date").toString());
                    }
                    else if("attr" == elementName)
                    {
                        video->append(reader.attributes().value("tag").toString());
                        video->append(reader.readElementText());
                    }
                    else if("poster" == elementName)
                    {
                        video->append(reader.attributes().value("img").toString());
                    }
                    else if("page" == elementName)
                    {
                        video->append(reader.attributes().value("link").toString());
                    }
                    else if("playtimes" == elementName)
                    {
                        video->append(reader.readElementText());
                    }
                }// reader is startElement
                else if(reader.isEndElement())
                {
                    elementName = reader.name();
                    if("video" == elementName)
                    {
                        m_videos.append(video);
                        video = 0;
                    }
                }
            }//while is end
    
            file.close();
            if(reader.hasError())
            {
                m_bError = true;
                m_strError = reader.errorString();
            }
        }
    
            void reset()
            {
                m_bError = false;
                m_strError.clear();
                clear();
            }
    
            void clear()
            {
                int count = m_videos.size();
                if(count > 0)
                {
                    for(int i = 0; i < count; i++)
                        delete m_videos.at(i);
    
                    m_videos.clear();
                }
    
            }
    
    public:
        QString m_strXmlFile;
        QString m_strError;
        bool m_bError;
        QHash<int, QByteArray> m_roleNames;
        QVector<VideoData*> m_videos;
    };
    
    VedioListModel::VedioListModel(QObject* parent)
        :QAbstractListModel(parent), m_dptr(new VideoListModelPrivate)
    {    
    }
    
    VedioListModel::~VedioListModel()
    {
        delete m_dptr;
    }
    
    int VedioListModel::rowCount(const QModelIndex &parent) const
    {
        return m_dptr->m_videos.size();
    }
    
    QVariant VedioListModel::data(const QModelIndex &index, int role) const
    {
        VideoData *d = m_dptr->m_videos[index.row()];
        return d->at(role - Qt::UserRole);
    }
    
    QHash<int, QByteArray> VedioListModel::roleNames() const
    {
        return m_dptr->m_roleNames;
    }
    
    QString VedioListModel::source()
    {
        return m_dptr->m_strXmlFile;
    }
    
    void VedioListModel::setSource(const QString &filePath)
    {
        m_dptr->m_strXmlFile = filePath;
        reload();
    
        if(m_dptr->m_bError)
            qDebug()<<"VideoListMode , error-"<<m_dptr->m_strError;
    }
    
    QString VedioListModel::errorString() const
    {
        return m_dptr->m_strError;
    }
    
    bool VedioListModel::hasError() const
    {
        return m_dptr->m_bError;
    }
    
    void VedioListModel::reload()
    {
        beginResetModel();
        m_dptr->reset();
        m_dptr->load();
        endResetModel();
    }
    
    void VedioListModel::remove(int index)
    {
        beginRemoveRows(QModelIndex(), index, index);
        delete m_dptr->m_videos.takeAt(index);
        endRemoveRows();
    }

     再来看main.qml文件

      

    import QtQuick 2.2
    import QtQuick.Window 2.1
    import QtQuick.Layouts 1.1
    import an.qt.CModel 1.0
    
    Window{
        visible: true
         360
        height: 400
        color: "#EEEEEE"
    
        Component{
            id: videoDelegate
            Item {
                id: wrapper
                 parent.width
                height: 120
    
                MouseArea{
                    anchors.fill: parent
                    onClicked: wrapper.ListView.view.currentIndex = index
                }
    
                Image{
                    id: poster
                    anchors.left: parent.left
                    anchors.top: parent.top
                    source: img
                     80
                    height: 120
                    fillMode: Image.PreserveAspectFit
                }//image is end
    
                ColumnLayout{
                    anchors.left: poster.right
                    anchors.leftMargin: 4
                    anchors.right: wrapper.right
                    anchors.top: poster.top
                    height: parent.height
                    spacing: 2
    
                    Text{
                        Layout.fillWidth: true
                        text: "<b>" + name + "</b>(" + rating + "," + playtimes + ")";
                        color: wrapper.ListView.isCurrentItem ? "blue" : "black"
                        font.pixelSize: 18
                        elide: Text.ElideRight
                    }
    
                    Text{
                        Layout.fillWidth: true
                        text: date
                        color: wrapper.ListView.isCurrentItem ? "blue" : "black"
                        font.pixelSize: 18
                        elide: Text.ElideRight
                    }
    
                    Text{
                        Layout.fillWidth: true
                        text: director_tag + ":<font color =#0000aa">" + director + "</font>"
                        color: wrapper.ListView.isCurrentItem ? "blue" : "black"
                        font.pixelSize: 18
                        elide: Text.ElideRight
                    }
    
                    Text{
                        Layout.fillWidth: trues
                        text:  actor_tag + ":<font color=#0000aa">" + actor + "</font>"
                        color: wrapper.ListView.isCurrentItem ? "blue" : "black"
                        font.pixelSize: 18
                        elide: Text.ElideRight
                    }
    
                    Text{
                        Layout.fillWidth: true
                        Layout.fillHeight: true
                        text: desc
                        color: wrapper.ListView.isCurrentItem ? "blue" : "black"
                        font.pixelSize: 16
                        wrapMode: Text.wrapMode
                        maximumLineCount: 2
                        elide: Text.ElideRight
                    }
                }//ColumnLayout is end
            }
        }//videoDelegate is end
    
        ListView{
            id: listView
            anchors.fill: parent
            spacing: 4
            delegate: videoDelegate
            model: VedioListModel{source: ":/videos.xml";}
            focus: true
            highlight: Rectangle{
                color: "lightblue"
            }
        }
    }

      最后是C++类的注册,在main.cpp中

      

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QtQml/QtQml>
    #include <QQuickView>
    #include "vediolistmodel.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        qmlRegisterType<VedioListModel>("an.qt.CModel", 1, 0, "VedioListModel");
    
    //    QQuickView view;
    //    view.setResizeMode(QQuickView::SizeRootObjectToView);
    //    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    //    view.show();
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    
        return app.exec();
    }
  • 相关阅读:
    一些性能查询的SQL 备忘
    Oracle Stream配置详细步骤
    Oracle 一次生产分库,升级,迁移
    Oracle数据文件和临时文件的管理
    db_recovery_file_dest_size 修改大一点及删除归档日志 |转|
    android启动优化
    C++ primer 中文第三版 阅读笔记 第八章
    XMPP通讯开发-好友获取界面设计
    用SHELL与列表处理了件尴尬事
    各种快递查询--Api接口
  • 原文地址:https://www.cnblogs.com/SaveDictator/p/8244247.html
Copyright © 2011-2022 走看看