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();
    }
  • 相关阅读:
    Good Bye 2014 B. New Year Permutation(floyd )
    hdu 5147 Sequence II (树状数组 求逆序数)
    POJ 1696 Space Ant (极角排序)
    POJ 2398 Toy Storage (叉积判断点和线段的关系)
    hdu 2897 邂逅明下 (简单巴什博弈)
    poj 1410 Intersection (判断线段与矩形相交 判线段相交)
    HDU 3400 Line belt (三分嵌套)
    Codeforces Round #279 (Div. 2) C. Hacking Cypher (大数取余)
    Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings (容斥原理)
    hdu 1576 A/B (求逆元)
  • 原文地址:https://www.cnblogs.com/SaveDictator/p/8244247.html
Copyright © 2011-2022 走看看