C++;Qt中QML插槽的信号 < >我想把一个C++的信号发送到QML文件中的一个槽中。 我已经让它在没有和基元类型参数的情况下工作,尽管如果我想向我的QML插槽发送QString,我在连接时会出错
我在main.cpp中连接C++;Qt中QML插槽的信号 < >我想把一个C++的信号发送到QML文件中的一个槽中。 我已经让它在没有和基元类型参数的情况下工作,尽管如果我想向我的QML插槽发送QString,我在连接时会出错,c++,qt,qml,signals-slots,C++,Qt,Qml,Signals Slots,我在main.cpp中连接 QObject *contentView = rootObject->findChild<QObject*>(QString("contentView")); QObject::connect(&myObj, SIGNAL(finishedGatheringDataForItem(QString)), contentView, SLOT(updateViewWithItem(QString)));
QObject *contentView = rootObject->findChild<QObject*>(QString("contentView"));
QObject::connect(&myObj, SIGNAL(finishedGatheringDataForItem(QString)),
contentView, SLOT(updateViewWithItem(QString)));
错误:
Object::connect: No such slot QDeclarativeRectangle_QML_2::updateViewWithItem(QString)
我认为最好查看本教程: 特别是本节: 我认为你在这个案例中的错误可能是你没有将它声明为插槽,或者你没有使它成为发票。这两个选项在Qt教程中都有说明
还需要使用QFAXT来交换C++与QML之间的数据。 您还可以注册类型,例如小部件和其他东西,以便在QML中将它们作为“本机”类型(如矩形)使用。在大多数情况下,不建议这样做,除非您需要某些外部类或某些无法在QML接口中显示的数据
QVariant的原因是QML基于脚本的方法。QVariant基本上包含您的数据和数据类型的描述,以便QML知道如何正确处理它。这就是为什么必须在QML中用String、int等指定参数。。但与C++的原始数据交换仍然是q变体< /p> 我以前使用过qmlRegisterType,但是对于简单的数据类型来说,它是一个非常不方便的解决方案。它更适合用于更复杂的数据,如定制小部件、画布或视频元素,QML本机不支持或扩展QStandardItemModels
。它是一种更方便的方法,在QML和C++之间交换数据,不需要在第一个实例中使用信号或时隙,因为QStaleReTimeMeod自动更新GUI。要使用QStandardItemModel,您需要向qmlRegisterType注册类型。然后可以在基于模型的视图(如ListView等)中使用该模型
我为这个主题附上了一个教程,它描述了如何使用QListModel
在这种情况下,您应该使用(可能这是连接的唯一方式)
setContextProperty
qmlVectorForm->rootContext()->setContextProperty("YourObject", myOb);
finishedGatheringDataForItem(QString signalString)
Connections {
target: YourObject
onFinishedGatheringDataForItem: {
qmlString = signalString
}
}
无连接的解决方案和任何上下文都不是通过连接信号插槽,而是通过连接信号插槽。建立 示例代码如下所示 qml: 后台类的头文件包含
public signals:
void cppSend(QString textOut);
public slots:
void cppReceive(QString textIn);
main.cpp通过以下方式连接它们:
1.从qml到cpp:
QObject::connect(qmlRootObject, SIGNAL(qmlSend(QString)),
backgroundObject, SLOT(cppReceive(QString)));
2.从cpp到qml:
QObject::connect(backgroundObject, SIGNAL(cppSend(QString)),
qmlRootObject, SIGNAL(qmlReceive(QString)));
为什么不使用rootContext呢 在C++方面,你有:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
//--------------------------------------------------------
#include <myClass.h>
//--------------------------------------------------------
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
//--------------------------------------------------------
myClass * myobj = new myClass(&app);
//--------------------------------------------------------
//--------------------------------------------------------
engine.rootContext()->setContextProperty("myobj",myobj);
//--------------------------------------------------------
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();
}
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
id: window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
//--------------------------------------------------------
Component.onCompleted: {
myobj.onSomeSignal.connect(signalHandling)
}
//--------------------------------------------------------
//--------------------------------------------------------
function signalHandling(){
console.log("Signal emitted from c++ side")
}
//--------------------------------------------------------
}
我已经尝试了很多解决方案来成功地从一个C++信号中更新QML,但是很多都没有用。 这个解决方案是有效的,并且已经过测试,它基于这个答案:(作者@Adriano Campos) <>你可以用信号发送C++到QML,比如: main.cpp:
#include <QQmlContext>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
// Class init
YourClass yourObject;
// Embedding C++ Objects into QML with Context Properties
QQmlContext* ctx = engine.rootContext();
ctx->setContextProperty("yourObject", &yourObject);
return app.exec();
}
yourClass.h:
class YourClass : public QObject
{
Q_OBJECT
signals:
// Signal from YourClass
void signalData(QString signal_param);
}
yourClass.cpp:
emit signalData("Hello QML"); // Signal from yourClass
一个完整的教程,关于如何将带有QT的信号和时隙的QT C++类公开到这个页面上:
您的UpDeVIEWWWITH项中没有QStand参数吗?(错误指出)抱歉,测试后忘记再次添加。但仍然不起作用。我尝试了UpDeVIEWWWEY(QString)和UpDeVeWiWiWiWiTew(String)。C++的信号意味着C++库或Qt类??谢谢,这个Q/A真的帮助了我。作为将来的参考,这里有一个很好的例子:我在这里不使用QDeclarativeView子类。正如我在我的问题中指出的,如果我不考虑参数,一切都会起作用。我必须以某种方式将QString引入我的QML吗?在这种情况下,尝试使用QVariant。我有几次遇到这个问题,QML不能识别QVariant以外的其他数据类型。嘿,这为我解决了这个问题!仍然在想是否有更好的解决方案。有没有试过使用qmlRegisterType?我刚刚更新了上面的回复。如果足够,请将其标记为答案。QML文件中的何处?当以高频或大量交换数据时,这可能会导致UI延迟。请确保信号插槽不总是具有良好的性能。所以为了优化,您应该在通过信号发送数据之前对其进行处理。在某些情况下,如果在两个线程之间连接,plz注意到不要以如此高的速率发送信号,这将导致UI卡住。您应该建立一种机制来控制发送频率(可能使用定时器或延迟)@HorusKol将连接
对象放在应该接收连接的QML组件中。它通常是根组件。看到例子我仍然无法使用的主要区别是QML的方式做这件事和良好的旧C++代码。基本上,插槽是在内部生成的,无需手动定义(因为在QML中,插槽基本上是信号
偏差的一个侧面特征)。
import QtQuick 2.6
Window {
id: mainWindow
Connections {
target: yourObject
onSignalData: {
console.log("Data: " + signal_param)
textToChange.text = "Changed to: " + signal_param
}
}
Text {
id: textToChange
text: "beforeChange"
}
}
class YourClass : public QObject
{
Q_OBJECT
signals:
// Signal from YourClass
void signalData(QString signal_param);
}
emit signalData("Hello QML"); // Signal from yourClass