Skip to main content
 首页 » 编程设计

qt之如何将列表从 C++ 公开到 Qml

2025年04月02日16小虾米

我想从 C++ 向 Qml 公开一个 QStringlist 列表,并从 QML 端访问其元素及其方法。

这是我到目前为止所做的:

这是我的一个名为 manager 的类的 .h 文件。

#include <QObject> 
#include <QStringList> 
#include <QList> 
 
class Manager : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QStringList imagesPaths READ imagesPaths) 
    Q_PROPERTY(QStringList imagesPaths READ imagesPaths2) 
    Q_PROPERTY(QList<QStringList> imagesPathsLists READ imagesPathsLists) 
 
public: 
    explicit Manager(QObject *parent = 0); 
 
    QStringList imagesPaths() const; 
    QStringList imagesPaths2() const; 
    QList<QStringList> imagesPathsLists()const; 
 
signals: 
 
public slots: 
 
private: 
    QStringList m_imagesPaths; 
    QStringList m_imagesPaths2; 
    QList<QStringList> m_imagesPathsLists; 
 
}; 

这是我的类方法实现的 .CPP 文件
#include "manager.h" 
 
Manager::Manager(QObject *parent) : 
    QObject(parent) 
{ 
    m_imagesPaths << "one" << "two" << "three" << "four"; 
    m_imagesPaths2 << "one-2" << "two-2" << "three-2" << "four-2"; 
    m_imagesPathsLists << m_imagesPaths << m_imagesPaths2; 
} 
 
QStringList Manager::imagesPaths() const 
{ 
    return m_imagesPaths; 
} 
 
QStringList Manager::imagesPaths2() const 
{ 
    return m_imagesPaths2; 
} 
 
QList<QStringList> Manager::imagesPathsLists() const 
{ 
    return m_imagesPathsLists; 
} 

以及包含我的类(class)注册的 main.cpp 文件
#include <QtGui/QGuiApplication> 
#include "qtquick2applicationviewer.h" 
#include <qqmlcontext.h> 
#include "manager.h" 
int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 
 
    QtQuick2ApplicationViewer viewer; 
 
    Manager *mng = new Manager(); 
    QQmlContext *ctxt = viewer.rootContext(); 
    ctxt->setContextProperty("Manager",mng); 
 
    viewer.setMainQmlFile(QStringLiteral("qml/listOfLists/main.qml")); 
    viewer.showExpanded(); 
 
    return app.exec(); 
}  

最后是试图从列表中获取数据的 .Qml 文件
import QtQuick 2.0 
 
Rectangle { 
    width: 360 
    height: 360 
 
    MouseArea { 
        anchors.fill: parent 
        onClicked: { 
            for(var i = 0; i < Manager.imagesPathsLists.count(); i++){ 
                for(var j = 0; j < Manager.imagesPathsLists[i].count(); j++){ 
                    console.log(Manager.imagesPathsLists[i].at(j)) 
                } 
            } 
        } 
    } 
} 

每当我单击矩形时,都会出现以下错误
QMetaProperty::read: Unable to handle unregistered datatype 'QList<QStringList>' for property 'Manager::imagesPathsLists' 
file:///E:/DevWork/build-listOfLists-Desktop_Qt_5_2_1_MinGW_32bit-Debug/qml/listOfLists/main.qml:10: TypeError: Cannot call method 'count' of undefined 

我已经尝试解决这个问题两天了。我试过 QQmlList属性但没有成功,我不知道我搞砸了什么。

请您参考如下方法:

您可以通过简单地输入 QList<QStringList> 来实现您想要做的事情。在从 QObject 派生的容器类中。下面的例子将解释它。

列表列表.h

#ifndef LISTOFLIST_H 
#define LISTOFLIST_H 
 
#include <QObject> 
#include <QStringList> 
class ListOfList : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit ListOfList(QObject *parent = 0); 
    void setListOfList(const QList<QStringList>& listOfList); 
    Q_INVOKABLE qint32 count() const; 
    Q_INVOKABLE qint32 subCount(const int & index) const; 
    Q_INVOKABLE QString at(const int &i,const int &j); 
signals: 
 
public slots: 
 
private: 
    QList<QStringList> m_listOfList; 
}; 
 
#endif // LISTOFLIST_H 

listoflist.cpp
#include "listoflist.h" 
 
ListOfList::ListOfList(QObject *parent) : 
    QObject(parent) 
{ 
} 
 
void ListOfList::setListOfList(const QList<QStringList> &listOfList) 
{ 
    m_listOfList = listOfList; 
} 
 
qint32 ListOfList::count() const 
{ 
    return m_listOfList.count(); 
} 
 
qint32 ListOfList::subCount(const int &index) const 
{ 
    int subCount = -1; 
    if(index>=0 && index<m_listOfList.count()) 
    { 
        subCount = m_listOfList.at(index).count(); 
    } 
    return subCount; 
} 
 
QString ListOfList::at(const int &i, const int &j) 
{ 
    QString value; 
    if(i>=0 && i<m_listOfList.count()) 
    { 
        if(j>=0 && j<m_listOfList.at(i).count()) 
        { 
            value = m_listOfList.at(i).at(j); 
        } 
    } 
    return value; 
} 

经理.h
#include <QObject> 
#include <QStringList> 
#include <QList> 
#include <listoflist.h> 
class Manager : public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QStringList imagesPaths READ imagesPaths) 
    Q_PROPERTY(QStringList imagesPaths READ imagesPaths2) 
    Q_PROPERTY(QObject* imagesPathsLists READ imagesPathsLists) 
 
public: 
    explicit Manager(QObject *parent = 0); 
 
    QStringList imagesPaths() const; 
    QStringList imagesPaths2() const; 
    QObject* imagesPathsLists(); 
 
signals: 
 
public slots: 
 
private: 
    QStringList m_imagesPaths; 
    QStringList m_imagesPaths2; 
    QList<QStringList> m_imagesPathsLists; 
    ListOfList m_listOfList; 
 
}; 

管理器.cpp
#include "manager.h" 
 
Manager::Manager(QObject *parent) : 
    QObject(parent) 
{ 
    m_imagesPaths << "one" << "two" << "three" << "four"; 
    m_imagesPaths2 << "one-2" << "two-2" << "three-2" << "four-2"; 
    m_imagesPathsLists << m_imagesPaths << m_imagesPaths2; 
    m_listOfList.setListOfList(m_imagesPathsLists); 
} 
 
QStringList Manager::imagesPaths() const 
{ 
    return m_imagesPaths; 
} 
 
QStringList Manager::imagesPaths2() const 
{ 
    return m_imagesPaths2; 
} 
 
QObject *Manager::imagesPathsLists() 
{ 
    return &m_listOfList; 
} 

主程序
#include <QtGui/QGuiApplication> 
#include "qtquick2applicationviewer.h" 
#include <qqmlcontext.h> 
#include "manager.h" 
int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 
 
    QtQuick2ApplicationViewer viewer; 
 
    Manager *mng = new Manager(); 
    QQmlContext *ctxt = viewer.rootContext(); 
    ctxt->setContextProperty("Manager",mng); 
 
    viewer.setMainQmlFile(QStringLiteral("qml/SO_ListOfLists/main.qml")); 
    viewer.showExpanded(); 
 
       return app.exec(); 
} 

主文件
import QtQuick 2.0 
 
Rectangle { 
    width: 360 
    height: 360 
    Text { 
        text: qsTr("Hello World") 
        anchors.centerIn: parent 
    } 
    MouseArea { 
        anchors.fill: parent 
        onClicked: { 
            var count = Manager.imagesPathsLists.count(); 
            for(var i=0;i<count;i++) 
            { 
                var subCount = Manager.imagesPathsLists.subCount(i); 
                console.debug("StringList number ->" + (i+1)) 
                for(var j=0;j<subCount;j++) 
                { 
                    var string = Manager.imagesPathsLists.at(i,j) 
                    console.debug(string) 
                } 
                console.debug("---------------------"); 
            } 
        } 
    } 
}