代码之家  ›  专栏  ›  技术社区  ›  laurapons

将信号从QML连接到Qt:var到QList<QString>

  •  2
  • laurapons  · 技术社区  · 7 年前

    我正在尝试将QML的信号连接到Qt的插槽。该信号传递一个QList变量。

    QML:

    property var cases: ["A", "B", "C"]
    
    signal casesClicked(list cases)
    

    Qt:

    d->m_view->setSource(QUrl("qrc:/qml/main.qml"));
    d->m_item = d->m_view->rootObject();
    QObject::connect(d->m_item, SIGNAL(casesClicked(QList<QString>)), this, SLOT(onCasesClicked(QList<QString>)));
    

    我遇到的问题是,我不知道如何从QML方面声明QList,所以直接使用它。如果我声明:

    signal casesClicked(var cases)
    

    然后,信号没有连接,如果我把它声明为一个列表或数组 "Invalid signal parameter type: list/Array"

    有小费吗?我对单int、bool或string没有任何问题。谢谢

    2 回复  |  直到 6 年前
        1
  •  1
  •   eyllanesc Yonghwan Shin    7 年前

    我认为在C++端建立连接是不合适的,因为编译时它不知道在QML中创建的信号,一个可能的解决方案是在QML端建立连接。下面我将展示一个示例

    主要的cpp公司

    #include <QGuiApplication>
    #include <QQuickView>
    #include <QQmlContext>
    #include <QDebug>
    class Test: public QObject{
    QQuickView *view;
    Q_OBJECT
    public:
        Test(QObject *parent=Q_NULLPTR):QObject(parent)
        {
            view = new QQuickView;
            view->rootContext()->setContextProperty("Test", this);
            view->setSource(QUrl("qrc:/main.qml"));
            view->show();
        }
    public slots:
        void onCasesClicked(QVariantList cases){
            qDebug()<<cases;
        }
    };
    
    int main(int argc, char *argv[])
    {
    #if defined(Q_OS_WIN)
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    #endif
    
        QGuiApplication app(argc, argv);
        Test test;
        return app.exec();
    }
    
    #include "main.moc"
    

    主要的qml公司

    import QtQuick 2.9
    
    Item {
        id: it
        visible: true
        width: 640
        height: 480
    
        signal casesClicked(var cases)
    
        MouseArea {
            id: mouseArea
            anchors.fill: parent
            onClicked: it.casesClicked(["B", 1, "D"])
        }
    
        Connections{
            target: it
            onCasesClicked: Test.onCasesClicked(cases)
        }
        // or
        // onCasesClicked: Test.onCasesClicked(cases)
        // if the connection is made in the same item
    }
    

    输出:

    (QVariant(QString, "B"), QVariant(int, 1), QVariant(QString, "D"))
    
        2
  •  1
  •   dtech    7 年前

    IIRC JS数组转换为 QVariantList 在C++中,请尝试使用它。

    编辑:

    好的,虽然上面是默认的自动转换,但当连接是从C++建立时,由于某种原因,它不起作用。

    在这种情况下,信号值转换为 QVariant 相反,它可以直接转换为 QStringList 这很方便。然而,如果您有一个包含不同数据类型的JS数组,那么这种方法将不起作用,这是完全合法的,并且在JS中经常使用。

    QVariantList 如果将JS数组作为参数传递给C++函数调用,则仍然可以使用。因此,您可以迭代每个值并处理“多态”数组。

    从C++创建到QML对象的连接是否是建议的做法取决于使用场景,总的来说,我认为不是。建议的做法是将C++核心接口公开到QML,并从那里进行连接,避免接触任何来自C++的QML。但也有一些特殊情况可以例外。