将信号从 QML 连接到 Qt:var 到 QList<QString>
Connecting signals from QML to Qt: var to QList<QString>
我正在尝试将来自 QML 的信号连接到来自 Qt 的 SLOT。信号传递一个 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 没有任何问题。谢谢,
IIRC JS 数组在 C++ 中被转换为 QVariantList
,因此请尝试使用它。
编辑:
好吧,看来上面虽然是默认的自动转换,但是在从C++连接的时候不知道为什么就不行了
在这种情况下,信号值被转换为 QVariant
,可以直接转换为 QStringList
,这很方便。然而,如果你有一个包含不同数据类型的 JS 数组,这种方法将不起作用,这是完全合法的,并且在 JS 中经常使用。
如果您将 JS 数组作为参数传递给 C++ 函数调用,QVariantList
仍然有效。所以你可以迭代每个值并处理一个 "polymorphic" 数组。
是否推荐从 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"
main.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"))
我正在尝试将来自 QML 的信号连接到来自 Qt 的 SLOT。信号传递一个 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 没有任何问题。谢谢,
IIRC JS 数组在 C++ 中被转换为 QVariantList
,因此请尝试使用它。
编辑:
好吧,看来上面虽然是默认的自动转换,但是在从C++连接的时候不知道为什么就不行了
在这种情况下,信号值被转换为 QVariant
,可以直接转换为 QStringList
,这很方便。然而,如果你有一个包含不同数据类型的 JS 数组,这种方法将不起作用,这是完全合法的,并且在 JS 中经常使用。
QVariantList
仍然有效。所以你可以迭代每个值并处理一个 "polymorphic" 数组。
是否推荐从 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"
main.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"))