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

C++ 将信号从QML连接到Qt:var到QList<;QString>;,c++,qt,qml,qt5,qt-signals,C++,Qt,Qml,Qt5,Qt Signals,我正在尝试将来自QML的信号连接到来自Qt的插槽。该信号传递一个QList变量 QML: Qt: 然后,信号未连接,如果我将其声明为列表或数组,它会显示“无效信号参数类型:列表/数组” 有小费吗?我对单int、bool或string没有任何问题。谢谢, iRCJS数组在C++中转换为QValueTalp,所以尝试使用它。 编辑: OK,虽然上面是默认的自动转换,但是当连接是由C++生成的时,它不起作用。 在这种情况下,信号值被转换为QVariant,可以直接转换为方便的QStringList

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

QML:

Qt:

然后,信号未连接,如果我将其声明为列表或数组,它会显示“无效信号参数类型:列表/数组”


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

iRCJS数组在C++中转换为QValueTalp,所以尝试使用它。 编辑:

OK,虽然上面是默认的自动转换,但是当连接是由C++生成的时,它不起作用。 在这种情况下,信号值被转换为

QVariant
,可以直接转换为方便的
QStringList
。但是,如果您有一个包含不同数据类型的JS数组,那么这种方法将不起作用,这是完全合法的,并且在JS中经常使用

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


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

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

main.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"
输出:

(QVariant(QString, "B"), QVariant(int, 1), QVariant(QString, "D"))

我正在使用Qt上其他函数的插槽,所以我试图避免在可能的情况下从Qt端更改类型。。。还有其他选项吗?没有,这是在QML引擎中设置的-JS数组变成QVariantList-就这么简单,如果需要,迭代QVariantList并从中填充字符串列表。请注意,Qt还有一个QStringList专门化,这比使用QList更好。请记住,JS数组不是类型化的,所以您需要使用变体作为中介,这是不可避免的。它适用于整数和布尔,因为类型是已知的。好的,谢谢。我应该如何声明QML边上的变量来将它识别为Qt上的QValeType列表?你不必做任何事情,任何JS数组在传递给C++时都会被转换成QVALITENLIST。正如任何JS对象都将转换为QVariantMap一样,我可能做错了什么,因为通过设置connect with QVariantList:QObject::connect(d->m_项,信号(casesClicked(QVariantList)),这个插槽(onCasesClicked(QVariantList)),并没有调用插槽;在这种情况下,
Connections
元素是多余的,因为在此上下文中您可以直接访问信号处理程序挂钩。您只需要
onCasesClicked:Test.onCasesClicked(cases)
部分。@dtech是的,我知道,但是如果在同一项中没有给出您所说的不起作用的连接,我的示例很简单。
signal casesClicked(var cases)
#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"
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"))