QML ListView elements(images) mix-up
-
I have
QAbstractListModel(c++)
that get images from the server.
then i created aListView
and use theQAbstractListModel(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:
But in rare occasions the images will mix-up, and the app will look like these:
If u look very carefully u will notice that the stove(product) is added where the supplier icon should be
-
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...