QML ListView elements(images) mix-up



  • I have QAbstractListModel(c++)that get images from the server.
    then i created a ListView and use the QAbstractListModel(c++) to delegete images.

    Now my problem is that in rare occasion (1/10) the images will mix-up and go where it is not suppose to be.

    FOR EXAMPLE
    These is an application of suppliers and products they offer,
    The App is suppose to look like these:

    0_1506071682809_Screenshot_2017-09-22-11-05-32.png


    But in rare occasions the images will mix-up, and the app will look like these:

    0_1506071814337_Screenshot_2017-09-22-11-05-32.png


    If u look very carefully u will notice that the stove(product) is added where the supplier icon should be



  • @chawila I would guess the problem is in the c++ model. Add some debugging output there and try to find out when it happens. If you don't succeed you should show the code, it's impossible to say anything without seeing it.



  • @Eeli-K

    ok i used the MVC framework idea, so i have the controller class which create the model and Model class its self.
    Then i created the crontrollers and make request in the main.cpp and pass them to qml with setContext.

    in the qml i have the a ListView that delegete the model so here is the code.


    ProductsController.h

    #ifndef REQUESTER_H
    #define REQUESTER_H
    
    #include <QObject>
    #include <QNetworkAccessManager>
    #include <QNetworkReply>
    #include <QString>
    
    #include <productsModel.h>
    
    class ProductsController : public QObject
    {
        Q_OBJECT
    
        Q_PROPERTY(QList<QObject*> prList READ prList  NOTIFY prListChanged)
    
    public:
        explicit ProductsController(QObject *parent = nullptr);
    
        Q_INVOKABLE void makeRequest(QString request);
    
    
        Q_INVOKABLE void clearList();
        QList<QObject*> prList();
    
    signals:
        void dataReadyRead(QString info);
        void prListChanged();
    
    public slots:
        void readyRead(QNetworkReply *reply);
    
    private:
    
        QNetworkAccessManager *netMan;
        QList<QObject*> productsModelList;
        QString returnInfo;
    };
    
    #endif // REQUESTER_H
    
    

    ProductsController.cpp

    #include "productsController.h"
    
    
    ProductsController::ProductsController( QObject *parent) : QObject(parent)
    {
        netMan = new QNetworkAccessManager(this);
        connect(netMan, SIGNAL(finished(QNetworkReply*)), this, SLOT(readyRead(QNetworkReply*)) );
    }
    
    
    
    void ProductsController::makeRequest(QString request)
    {
        QNetworkRequest req;
        req.setUrl(QUrl(request) );
        req.setRawHeader( "User-Agent" , "AppName" );
    
        netMan->get(req);
    
    }
    
    void ProductsController::clearList()
    {
        productsModelList.clear();
    
    }
    
    
    QList<QObject*> ProductsController::prList()
    {
    
        return productsModelList;
    
    }
    
    
    
    void ProductsController::readyRead(QNetworkReply *reply)
    {
        returnInfo = reply->readAll();
    
        if(!returnInfo.trimmed().isEmpty()){
    
            QString products = returnInfo.replace("PricemateApp 17.1", "");
            QStringList productsList = products.split('^');
    
            for(int i =0; i < productsList.length(); i++){
    
                QStringList singleProduct = productsList[i].split('#');
    
                if(! singleProduct[0].trimmed().isEmpty()){
    
                    productsModelList.append(new ProductsModel(singleProduct[0], singleProduct[1], singleProduct[2], singleProduct[3], singleProduct[4]));
    
                }
            }
        }
    
        emit prListChanged();
    
    
    
    
    }
    
    

    Now the Models


    productsModel.h

    #ifndef FEATUREPRODUCTS_H
    #define FEATUREPRODUCTS_H
    
    #include <QObject>
    
    class ProductsModel : public QObject
    {
    
        Q_OBJECT
    
        Q_PROPERTY(QString prId    READ  prId        WRITE setPrId         NOTIFY prIdChanged)
    
        Q_PROPERTY(QString spIcon   READ  spIcon       WRITE setSpIcon        NOTIFY spIconChanged)
    
        Q_PROPERTY(QString prThumb  READ  prThumb      WRITE setPrThumb       NOTIFY prThumbChanged)
    
        Q_PROPERTY(QString prName   READ  prName       WRITE setPrName        NOTIFY prNameChanged)
    
        Q_PROPERTY(QString price    READ  price        WRITE setPrice         NOTIFY priceChanged)
    
    
    public:
        ProductsModel(QObject *parent=0);
    
        ProductsModel(const QString &pr_id, const QString &sp_icon, const QString &pr_thumb, const QString &pr_name, const QString &price, QObject *parent=0);
    
    
        //get product id
        QString prId() const;
    
        //set product id
        void setPrId(const QString &prId);
    
        //get supplier icon
        QString spIcon() const;
    
        //set supplier icon
        void setSpIcon(const QString &spIcon);
    
    
        //get product thumb
        QString prThumb() const;
    
        //set product thumb
        void setPrThumb(const QString &prThumb);
    
    
    
        //get product name
        QString prName() const;
    
        //set product name
        void setPrName(const QString &prName);
    
    
        //get product name
        QString price() const;
        //set product name
        void setPrice(const QString &price);
    
    
    signals:
    
        void prIdChanged();
        void spIconChanged();
        void prThumbChanged();
        void prNameChanged();
        void priceChanged();
    
    
    private:
        QString m_pr_id;
        QString m_sp_icon;
        QString m_pr_thumb;
        QString m_pr_name;
        QString m_price;
    
    
    };
    
    #endif // FEATUREPRODUCTS_H
    
    
    

    productsModel.cpp

    #include <QDebug>
    #include "productsModel.h"
    
    ProductsModel::ProductsModel(QObject *parent)  : QObject(parent){
    }
    
    ProductsModel::ProductsModel(const QString &prId, const QString &spIcon, const QString &prThumb, const QString &prName, const QString &price, QObject *parent)
     : QObject(parent), m_pr_id(prId),  m_sp_icon(spIcon), m_pr_thumb(prThumb), m_pr_name(prName), m_price(price)
    {
    
    }
    
    QString ProductsModel::prId() const
    {
        return m_pr_id;
    }
    
    void ProductsModel::setPrId(const QString &prId)
    {
        if(m_pr_id != prId){
            m_pr_id = prId;
            emit prIdChanged();
        }
    }
    
    
    
    //get supplier icon/logo
    QString ProductsModel::spIcon() const
    {
        return m_sp_icon;
    }
    
    //set supplier logo
    void ProductsModel::setSpIcon(const QString &spIcon)
    {
        if(m_sp_icon != spIcon){
            m_sp_icon = spIcon;
            emit spIconChanged();
        }
    }
    
    
    
    
    //get product thumb
    QString ProductsModel::prThumb() const
    {
        return m_pr_thumb;
    
    }
    
    //set product thumb
    void ProductsModel::setPrThumb(const QString &prThumb)
    {
        if (m_pr_thumb != prThumb) {
    
            m_pr_thumb = prThumb;
            emit prThumbChanged();
        }
    
    }
    
    
    
    //get product name
    QString ProductsModel::prName() const
    {
        return m_pr_name;
    }
    
    //set product name
    void ProductsModel::setPrName(const QString &prName)
    {
        if(m_pr_name != prName){
            m_pr_name = prName;
            emit prNameChanged();
        }
    }
    
    
    //get price
    QString ProductsModel::price() const
    {
        return m_price;
    
    }
    
    //set price
    void ProductsModel::setPrice(const QString &price)
    {
        if(m_price != price){
            m_price = price;
            emit priceChanged();
        }
    }
    
    

    Now in main.cpp

     /*
         * ===========================================
         * Products page object
         * ===========================================
         */
    
        ProductsController requestAllProducts ;
        requestAllProducts.makeRequest("make My custome request here");
    
    
        //all products model
        engine.rootContext()->setContextProperty("requestAllProducts", &requestAllProducts);
    
    

    Then in qml

                ListView{
    
                    id: featuredProductsGrid
                    width: parent.width * 0.9
                    height: 750
    
                    anchors.horizontalCenter: parent.horizontalCenter
                    spacing: 30
                    orientation: ListView.Horizontal
    
                    model: requestFeaturedProducts.prList
                    delegate:ProductsDel{}
    
                }
    

    Lastly the products delegete

    import QtQuick 2.0
    import QtQuick.Window 2.0
    import QtQuick 2.7
    import QtQuick.Controls 1.4
    
    import "ajax.js" as SingleProductjs
    
    
    
    Rectangle{
        id: productRect
        
        width: Screen.width / 2 * 0.87
        height: width + (Screen.width / 2 * 0.2)
        
        border.color: "#c7c7c7"
        border.width: 1
    
        
        Text {
            id: hiddenId
            visible: false
            text: model.modelData.prId
        }
        
        
        Column{
            
            id: pr_column
            anchors.horizontalCenter: productRect.horizontalCenter
            
            width: parent.width
            
            Rectangle{
                
                border.color: "#c7c7c7"
                border.width: 1
                width: parent.width
                height: 80
                
                
                Image {
                    
                    
                    source:  Qt.resolvedUrl(IMG_LINK+"Inc/Upload/Image/"+model.modelData.spIcon)
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.verticalCenter:  parent.verticalCenter
                    anchors.topMargin: 20
                    asynchronous: true
                    width: 110
                    height: 60
                    
                    
                    
                }
            }
            
            
            Rectangle{
                
                border.color: "#c7c7c7"
                border.width: 1
                width: parent.width
                height: productRect.width * 0.9
                
                BusyIndicator{
                    id: busyAnimation
                    anchors.centerIn: parent
                    
                    width: 100
                    height: width
                    running: pr_tumb_id.status === pr_tumb_id.Loading
                    
                    AnimatedImage{
                        source: "img/lib/load.gif"
                        width: parent.width * 0.7
                        height: parent.width * 0.7
                        anchors.horizontalCenter: parent.horizontalCenter
                        anchors.verticalCenter: parent.verticalCenter
                    }
                }
                
                Image {
                    
                    id: pr_tumb_id
                    source: Qt.resolvedUrl(IMG_LINK+"Inc/Upload/Image/thumbnail_"+model.modelData.prThumb)
                    width: parent.width * 0.7
                    height: parent.width * 0.7
                    asynchronous: true
                    
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.verticalCenter:  parent.verticalCenter
                    
                    MouseArea{
                        anchors.fill: parent
                        onClicked: {
                            
                            
                            singleProduct.clearList();
                            singleProduct.makeRequest(URL+"get.php?getProduct="+hiddenId.text)
                            pageLoader.source = "loading.qml"
                        }
                    }
                    
                }
                
                
                
                
                
            }
            
            
            Rectangle{
                
                border.color: "#c7c7c7"
                border.width: 1
                width: parent.width
                height: 200
                
                
                Column{
                    
                    anchors.horizontalCenter: parent.horizontalCenter
                    anchors.verticalCenter:  parent.verticalCenter
                    width: parent.width
                    
                    Rectangle{
                        width: parent.width * 0.8
                        height: parent.height * 0.8
                        anchors.horizontalCenter: parent.horizontalCenter
                        
                        TextMetrics {
                            id: textMetrics
                            font.family: "Arial"
                            elide: Text.ElideMiddle
    
                            elideWidth: parent.width
                            text: model.modelData.prName
                        }
                        
                        Text {
    
                            id: pr_name_id
                            text: textMetrics.text
                            color: "#09f"
                            width: parent.width
                            height: parent.height
                            wrapMode: Text.WordWrap
                            maximumLineCount: 3
                            elide: Text.ElideRight
                            
                        }
                    }
                    
                    Text {
                        text: "P " + model.modelData.price
                        color: "#bd0000"
                        
                        anchors.horizontalCenter: parent.horizontalCenter
                        
                    }
                }
                
            }
            
        }
        
    }
    
    
    
    


  • Hi.. precision is the key...
    this app is not enable in offline modus...
    Yesterday i tested XmlListModel .. & as cached file if not network the result is the same as online..
    http://doc.qt.io/qt-5/qml-qtquick-xmllistmodel-xmllistmodel.html
    i think your shop have a website.. & from sql to xml is not a long way .. && That way everything is simpler
    only as suggestion...



  • haha!...
    thanks @patrik08
    i really appreciate ur comment.
    i`m working on that.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.