आप QAbstractListModel के data फ़ंक्शन को कैसे कार्यान्वित कर सकते हैं जैसे कि यह कुछ गुणों के साथ लौटाता है जो QML ListView के प्रतिनिधि से दिखाई देते हैं?

आइटम प्रकार के लिए, मैंने एक QObject उपवर्ग को लागू करने का प्रयास किया जिसमें Q_PROPERTYs हैं, लेकिन QAbstractListModel::data रिटर्न QVariant, और एक QObject* को परिवर्तित नहीं किया जा सकता है QVariant?

मैं एक QVariant कैसे बनाऊं जिसमें QML के लिए दृश्यमान गुणों का नाम हो?

class MyListItem : public QObject {
  Q_OBJECT
  Q_PROPERTY(type name READ name WRITE set_name NOTIFY nameChanged)
  /*...*/
public:
  MyListItem(QObject* parent, const QString& name) : QObject(parent) {
    set_name(name);
  }
};

class MyList : public QAbstractListModel
{
public:
  MyList(QObject* parent);

  Q_INVOKABLE int rowCount(const QModelIndex &parent = QModelIndex()) const override;
  Q_INVOKABLE QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

  QVector<MyListItem*> items;
};

Q_INVOKABLE int MyList::rowCount(const QModelIndex &) const {
  return items.size();
}

Q_INVOKABLE QVariant MyList::data(const QModelIndex &index, int) const {
  MyListItem* item = items[index.row()];
  return item; // <--- ERROR
}

मिल रहा:

In member function ‘virtual QVariant MyList::data(const QModelIndex&, int) const’:
error: use of deleted function ‘QVariant::QVariant(void*)’
  18 |   return item;
     |          ^~~~
1
Andrew Tomazos 23 पद 2020, 06:53
कृपया एक न्यूनतम प्रतिलिपि प्रस्तुत करने योग्य उदाहरण प्रदान करें, और एक QVariant यदि इसमें QObject के लिए एक सूचक हो सकता है तो मुझे लगता है कि समस्या है एक और
 – 
eyllanesc
23 पद 2020, 07:01
@eyllanesc: अपडेट देखें। QObject* को QVariant में नहीं बदला जा सकता
 – 
Andrew Tomazos
23 पद 2020, 07:24

1 उत्तर

सबसे बढ़िया उत्तर

यदि आप किसी QObject को QVariant में इनकैप्सुलेट करना चाहते हैं तो आपको QVariant::fromValue का उपयोग करना चाहिए:

return QVariant::fromValue(item);

मेगावाट:

main.cpp

#include <QAbstractListModel>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

class MyListItem : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE set_name NOTIFY nameChanged)
public:
    MyListItem(const QString& name, QObject* parent=nullptr) : QObject(parent), m_name(name) {
    }
    QString name() const{
        return m_name;
    }
public slots:
    void set_name(QString name){
        if (m_name == name)
            return;
        m_name = name;
        emit nameChanged(m_name);
    }
signals:
    void nameChanged(QString name);
private:
    QString m_name;
};

class MyList : public QAbstractListModel
{
public:
    enum MyListRoles {
        ItemRole = Qt::UserRole + 1
    };
    MyList(QObject* parent=nullptr): QAbstractListModel(parent){}
    ~MyList(){
        qDeleteAll(items);
        items.clear();
    }
    void append(MyListItem *item){
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        items.append(item);
        endInsertRows();
    }
    int rowCount(const QModelIndex &parent=QModelIndex()) const override{
        if(parent.isValid())
            return 0;
        return items.count();
    }
    QVariant data(const QModelIndex &index, int role) const override{
        if(!index.isValid())
            return {};
        if(index.row() <0 || index.row() >= rowCount())
            return {};
        if(role == ItemRole)
            return QVariant::fromValue(items[index.row()]);
        return {};
    }
    QHash<int, QByteArray> roleNames() const override{
        return {{ItemRole, "item"}};
    }
private:
    QVector<MyListItem*> items;
};
#include "main.moc"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
    QGuiApplication app(argc, argv);
    MyList model;
    model.append(new MyListItem("foo1"));
    model.append(new MyListItem("foo2"));
    model.append(new MyListItem("foo3"));
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("mylist", &model);
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);
    return app.exec();
}

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    ListView{
        anchors.fill: parent
        model: mylist
        delegate: Text {
            text: model.item.name
        }
    }
}

enter image description here

3
eyllanesc 23 पद 2020, 07:44
1
धन्यवाद, यह बहुत मददगार था। साथ ही, एक हिस्सा जो मुझे याद आ रहा था वह था भूमिकाओं की धारणा। roleNames को लागू करने और QAbstractListModel::data के role पैरामीटर को देखने के बाद अब मैं इसे काम कर रहा हूं। (मैंने सोचा था कि ListView प्रतिनिधि में संदर्भ QObject के गुण थे - ऐसा नहीं है - वे भूमिका तंत्र का उपयोग कर रहे हैं)
 – 
Andrew Tomazos
23 पद 2020, 07:51