Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qdbusabstractinterface.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
7
8#include <qcoreapplication.h>
9#include <qthread.h>
10
11#include "qdbusargument.h"
12#include "qdbuspendingcall.h"
13#include "qdbusmessage_p.h"
14#include "qdbusmetaobject_p.h"
15#include "qdbusmetatype_p.h"
16#include "qdbusservicewatcher.h"
17#include "qdbusutil_p.h"
18
19#include <qdebug.h>
20
21#ifndef QT_NO_DBUS
22
24
25using namespace Qt::StringLiterals;
26
27namespace {
28// ### Qt6: change to a regular QEvent (customEvent)
29// We need to use a QMetaCallEvent here because we can't override customEvent() in
30// Qt 5. Since QDBusAbstractInterface is meant to be derived from, the vtables of
31// classes in generated code will have a pointer to QObject::customEvent instead
32// of to QDBusAbstractInterface::customEvent.
33// See solution in Patch Set 1 of this change in the Qt Gerrit servers.
34// (https://codereview.qt-project.org/#/c/126384/1)
35class DisconnectRelayEvent : public QAbstractMetaCallEvent
36{
37public:
38 DisconnectRelayEvent(QObject *sender, const QMetaMethod &m)
39 : QAbstractMetaCallEvent(sender, m.methodIndex())
40 {}
41
42 void placeMetaCall(QObject *object) override
43 {
46 }
47};
48}
49
50static QDBusError checkIfValid(const QString &service, const QString &path,
51 const QString &interface, bool isDynamic, bool isPeer)
52{
53 // We should be throwing exceptions here... oh well
55
56 // dynamic interfaces (QDBusInterface) can have empty interfaces, but not service and object paths
57 // non-dynamic is the opposite: service and object paths can be empty, but not the interface
58 if (!isDynamic) {
59 // use assertion here because this should never happen, at all
60 Q_ASSERT_X(!interface.isEmpty(), "QDBusAbstractInterface", "Interface name cannot be empty");
61 }
62 if (!QDBusUtil::checkBusName(service, (isDynamic && !isPeer) ? QDBusUtil::EmptyNotAllowed : QDBusUtil::EmptyAllowed, &error))
63 return error;
65 return error;
67 return error;
68
69 // no error
70 return QDBusError();
71}
72
74 const QString &p,
75 const QString &iface,
76 const QDBusConnection& con,
77 bool isDynamic)
78 : connection(con), service(serv), path(p), interface(iface),
79 lastError(checkIfValid(serv, p, iface, isDynamic, (connectionPrivate() &&
80 connectionPrivate()->mode == QDBusConnectionPrivate::PeerMode))),
81 timeout(-1),
82 interactiveAuthorizationAllowed(false),
83 isValid(!lastError.isValid())
84{
85 if (!isValid)
86 return;
87
88 if (!connection.isConnected()) {
91 }
92}
93
107
109{
110 // recheck only if we have a wildcard (i.e. empty) service or path
111 // if any are empty, set the error message according to QDBusUtil
114 if (path.isEmpty())
116 return true;
117}
118
119bool QDBusAbstractInterfacePrivate::property(const QMetaProperty &mp, void *returnValuePtr) const
120{
121 if (!isValid || !canMakeCalls()) // can't make calls
122 return false;
123
124 QMetaType type = mp.metaType();
125 // is this metatype registered?
126 const char *expectedSignature = "";
127 if (type.id() != QMetaType::QVariant) {
128 expectedSignature = QDBusMetaType::typeToSignature(type);
129 if (expectedSignature == nullptr) {
130 qWarning("QDBusAbstractInterface: type %s must be registered with Qt D-Bus before it can be "
131 "used to read property %s.%s",
132 mp.typeName(), qPrintable(interface), mp.name());
133 lastError = QDBusError(QDBusError::Failed, "Unregistered type %1 cannot be handled"_L1
134 .arg(QLatin1StringView(mp.typeName())));
135 return false;
136 }
137 }
138
139 // try to read this property
142 QStringLiteral("Get"));
144 msg << interface << QString::fromUtf8(mp.name());
146
147 if (reply.type() != QDBusMessage::ReplyMessage) {
149 return false;
150 }
151 if (reply.signature() != "v"_L1) {
152 QString errmsg =
153 "Invalid signature '%1' in return from call to " DBUS_INTERFACE_PROPERTIES ""_L1;
154 lastError = QDBusError(QDBusError::InvalidSignature, std::move(errmsg).arg(reply.signature()));
155 return false;
156 }
157
158 QByteArray foundSignature;
159 const char *foundType = nullptr;
160 QVariant value = qvariant_cast<QDBusVariant>(reply.arguments().at(0)).variant();
161
162 if (value.metaType() == type || type.id() == QMetaType::QVariant
163 || (expectedSignature[0] == 'v' && expectedSignature[1] == '\0')) {
164 // simple match
165 if (type.id() == QMetaType::QVariant) {
166 *reinterpret_cast<QVariant*>(returnValuePtr) = value;
167 } else {
168 QMetaType(type).destruct(returnValuePtr);
169 QMetaType(type).construct(returnValuePtr, value.constData());
170 }
171 return true;
172 }
173
174 if (value.metaType() == QMetaType::fromType<QDBusArgument>()) {
175 QDBusArgument arg = qvariant_cast<QDBusArgument>(value);
176
177 foundType = "user type";
178 foundSignature = arg.currentSignature().toLatin1();
179 if (foundSignature == expectedSignature) {
180 // signatures match, we can demarshall
181 return QDBusMetaType::demarshall(arg, QMetaType(type), returnValuePtr);
182 }
183 } else {
184 foundType = value.typeName();
185 foundSignature = QDBusMetaType::typeToSignature(value.metaType());
186 }
187
188 // there was an error...
189 const auto errmsg = "Unexpected '%1' (%2) when retrieving property '%3.%4' "
190 "(expected type '%5' (%6))"_L1;
192 errmsg.arg(QLatin1StringView(foundType),
193 QLatin1StringView(foundSignature),
194 interface,
195 QLatin1StringView(mp.name()),
196 QLatin1StringView(mp.typeName()),
197 QLatin1StringView(expectedSignature)));
198 return false;
199}
200
202{
203 if (!isValid || !canMakeCalls()) // can't make calls
204 return false;
205
206 // send the value
209 QStringLiteral("Set"));
211 msg << interface << QString::fromUtf8(mp.name()) << QVariant::fromValue(QDBusVariant(value));
212 QDBusMessage reply = connection.call(msg, QDBus::Block, timeout);
213
214 if (reply.type() != QDBusMessage::ReplyMessage) {
215 lastError = QDBusError(reply);
216 return false;
217 }
218 return true;
219}
220
222 const QString &oldOwner,
223 const QString &newOwner)
224{
225 Q_UNUSED(oldOwner);
226 //qDebug() << "QDBusAbstractInterfacePrivate serviceOwnerChanged" << name << oldOwner << newOwner;
228 currentOwner = newOwner;
229}
230
235
237{
238 int saved_id = _id;
239 _id = QObject::qt_metacall(_c, _id, _a);
240 if (_id < 0)
241 return _id;
242
244 QMetaProperty mp = metaObject()->property(saved_id);
245 int &status = *reinterpret_cast<int *>(_a[2]);
246
247 if (_c == QMetaObject::WriteProperty) {
249 if (mp.metaType() == QMetaType::fromType<QDBusVariant>())
250 value = reinterpret_cast<const QDBusVariant*>(_a[0])->variant();
251 else
252 value = QVariant(mp.metaType(), _a[0]);
253 status = d_func()->setProperty(mp, value) ? 1 : 0;
254 } else {
255 bool readStatus = d_func()->property(mp, _a[0]);
256 // Caller supports QVariant returns? Then we can also report errors
257 // by storing an invalid variant.
258 if (!readStatus && _a[1]) {
259 status = 0;
260 reinterpret_cast<QVariant*>(_a[1])->clear();
261 }
262 }
263 _id = -1;
264 }
265 return _id;
266}
267
295
302 const char *interface, const QDBusConnection &con,
303 QObject *parent)
305 con, false), parent)
306{
307 // keep track of the service owner
308 d_func()->initOwnerTracking();
309}
310
317
327{
328 Q_D(const QDBusAbstractInterface);
329 /* We don't retrieve the owner name for peer connections */
330 if (d->connectionPrivate() && d->connectionPrivate()->mode == QDBusConnectionPrivate::PeerMode) {
331 return d->isValid;
332 } else {
333 return !d->currentOwner.isEmpty();
334 }
335}
336
341{
342 return d_func()->connection;
343}
344
349{
350 return d_func()->service;
351}
352
357{
358 return d_func()->path;
359}
360
365{
366 return d_func()->interface;
367}
368
374{
375 return d_func()->lastError;
376}
377
385{
386 d_func()->timeout = timeout;
387}
388
396{
397 return d_func()->timeout;
398}
399
418{
419 d_func()->interactiveAuthorizationAllowed = enable;
420}
421
433{
434 return d_func()->interactiveAuthorizationAllowed;
435}
436
455 const QString& method,
456 const QList<QVariant>& args)
457{
459
460 if (!d->isValid || !d->canMakeCalls())
461 return QDBusMessage::createError(d->lastError);
462
463 QString m = method;
464 // split out the signature from the method
465 int pos = method.indexOf(u'.');
466 if (pos != -1)
467 m.truncate(pos);
468
469 if (mode == QDBus::AutoDetect) {
470 // determine if this a sync or async call
472 const QMetaObject *mo = metaObject();
473 QByteArray match = m.toLatin1();
474
475 for (int i = staticMetaObject.methodCount(); i < mo->methodCount(); ++i) {
476 QMetaMethod mm = mo->method(i);
477 if (mm.name() == match) {
478 // found a method with the same name as what we're looking for
479 // hopefully, nobody is overloading asynchronous and synchronous methods with
480 // the same name
481
482 QList<QByteArray> tags = QByteArray(mm.tag()).split(' ');
483 if (tags.contains("Q_NOREPLY"))
485
486 break;
487 }
488 }
489 }
490
491// qDebug() << "QDBusAbstractInterface" << "Service" << service() << "Path:" << path();
494 msg.setArguments(args);
495
496 QDBusMessage reply = d->connection.call(msg, mode, d->timeout);
498 d->lastError = QDBusError(reply); // will clear if reply isn't an error
499
500 // ensure that there is at least one element
501 if (reply.arguments().isEmpty())
502 reply << QVariant();
503
504 return reply;
505}
506
522 const QList<QVariant>& args)
523{
525
526 if (!d->isValid || !d->canMakeCalls())
527 return QDBusPendingCall::fromError(d->lastError);
528
531 msg.setArguments(args);
532 if (d->interactiveAuthorizationAllowed)
534 return d->connection.asyncCall(msg, d->timeout);
535}
536
562 const QList<QVariant> &args,
563 QObject *receiver,
564 const char *returnMethod,
565 const char *errorMethod)
566{
568
569 if (!d->isValid || !d->canMakeCalls())
570 return false;
571
573 path(),
574 interface(),
575 method);
577 msg.setArguments(args);
578
579 d->lastError = QDBusError();
580 return d->connection.callWithCallback(msg,
581 receiver,
582 returnMethod,
583 errorMethod,
584 d->timeout);
585}
586
606 const QList<QVariant> &args,
607 QObject *receiver,
608 const char *slot)
609{
610 return callWithCallback(method, args, receiver, slot, nullptr);
611}
612
618{
619 // someone connecting to one of our signals
621 if (!d->isValid)
622 return;
623
624 // we end up recursing here, so optimize away
626 if (signal == destroyedSignal)
627 return;
628
629 QDBusConnectionPrivate *conn = d->connectionPrivate();
630 if (conn) {
631 conn->connectRelay(d->service, d->path, d->interface,
632 this, signal);
633 }
634}
635
641{
642 // someone disconnecting from one of our signals
644 if (!d->isValid)
645 return;
646
647 // disconnection is just resource freeing, so it can be delayed;
648 // let's do that later, after all the QObject mutexes have been unlocked.
649 QCoreApplication::postEvent(this, new DisconnectRelayEvent(this, signal));
650}
651
657{
659 QDBusConnectionPrivate *conn = d->connectionPrivate();
660 if (!conn)
661 return;
662
663 const QMetaObject *mo = ptr->metaObject();
664 QMetaMethod signal = signalId >= 0 ? mo->method(signalId) : QMetaMethod();
665 if (signal.isValid()) {
666 if (!ptr->isSignalConnected(signal))
667 return conn->disconnectRelay(d->service, d->path, d->interface,
668 ptr, signal);
669 } else {
670 // wildcard disconnecting, we need to figure out which of our signals are
671 // no longer connected to anything
672 int midx = QObject::staticMetaObject.methodCount();
673 const int end = mo->methodCount();
674 for ( ; midx < end; ++midx) {
675 QMetaMethod mm = mo->method(midx);
676 if (mm.methodType() == QMetaMethod::Signal && !ptr->isSignalConnected(mm))
677 conn->disconnectRelay(d->service, d->path, d->interface, ptr, mm);
678 }
679 }
680}
681
687{
688 // assume this property exists and is readable
689 // we're only called from generated code anyways
690
691 return property(propname);
692}
693
699{
700 setProperty(propname, value);
701}
702
798 const QString &method,
799 const QList<QVariant> &args) const
800{
801 // ### move the code here, and make the other functions call this
802 return const_cast<QDBusAbstractInterface*>(this)->callWithArgumentList(mode, method, args);
803}
804
805QDBusMessage QDBusAbstractInterface::doCall(QDBus::CallMode mode, const QString &method, const QVariant *args, size_t numArgs)
806{
807 QList<QVariant> list;
808 list.reserve(int(numArgs));
809 for (size_t i = 0; i < numArgs; ++i)
810 list.append(args[i]);
812}
813
814QDBusPendingCall QDBusAbstractInterface::doAsyncCall(const QString &method, const QVariant *args, size_t numArgs)
815{
816 QList<QVariant> list;
817 list.reserve(int(numArgs));
818 for (size_t i = 0; i < numArgs; ++i)
819 list.append(args[i]);
821}
822
824
825#endif // QT_NO_DBUS
826
827#include "moc_qdbusabstractinterface.cpp"
\inmodule QtCore
Definition qbytearray.h:57
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
int qt_metacall(QMetaObject::Call, int, void **) override
QDBusAbstractInterfaceBase(QDBusAbstractInterfacePrivate &dd, QObject *parent)
static void finishDisconnectNotify(QDBusAbstractInterface *iface, int signalId)
QDBusAbstractInterfacePrivate(const QString &serv, const QString &p, const QString &iface, const QDBusConnection &con, bool dynamic)
bool setProperty(const QMetaProperty &mp, const QVariant &value)
QDBusConnectionPrivate * connectionPrivate() const
bool property(const QMetaProperty &mp, void *returnValuePtr) const
void _q_serviceOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
QVariant internalPropGet(const char *propname) const
QDBusPendingCall asyncCallWithArgumentList(const QString &method, const QList< QVariant > &args)
QDBusAbstractInterface(const QString &service, const QString &path, const char *interface, const QDBusConnection &connection, QObject *parent)
QString service() const
Returns the name of the service this interface is associated with.
void setTimeout(int timeout)
Sets the timeout in milliseconds for all future DBus calls to timeout.
bool isInteractiveAuthorizationAllowed() const
Returns whether, for asynchronous calls, the caller is prepared to wait for interactive authorization...
void disconnectNotify(const QMetaMethod &signal) override
QDBusConnection connection() const
Returns the connection this interface is associated with.
void internalPropSet(const char *propname, const QVariant &value)
void setInteractiveAuthorizationAllowed(bool enable)
Configures whether, for asynchronous calls, the caller is prepared to wait for interactive authorizat...
QString interface() const
Returns the name of this interface.
QString path() const
Returns the object path that this interface is associated with.
QDBusMessage callWithArgumentList(QDBus::CallMode mode, const QString &method, const QList< QVariant > &args)
Places a call to the remote method specified by method on this interface, using args as arguments.
bool isValid() const
Returns true if this is a valid reference to a remote object.
int timeout() const
Returns the current value of the timeout in milliseconds.
QDBusError lastError() const
Returns the error the last operation produced, or an invalid error if the last operation did not prod...
void connectNotify(const QMetaMethod &signal) override
QDBusMessage internalConstCall(QDBus::CallMode mode, const QString &method, const QList< QVariant > &args=QList< QVariant >()) const
bool callWithCallback(const QString &method, const QList< QVariant > &args, QObject *receiver, const char *member, const char *errorSlot)
Places a call to the remote method specified by method on this interface, using args as arguments.
virtual ~QDBusAbstractInterface()
Releases this object's resources.
\inmodule QtDBus
void disconnectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const QMetaMethod &signal)
QString getNameOwner(const QString &service)
void connectRelay(const QString &service, const QString &path, const QString &interface, QDBusAbstractInterface *receiver, const QMetaMethod &signal)
\inmodule QtDBus
bool isConnected() const
Returns true if this QDBusConnection object is connected.
QDBusMessage call(const QDBusMessage &message, QDBus::CallMode mode=QDBus::Block, int timeout=-1) const
Sends the message over this connection and blocks, waiting for a reply, for at most timeout milliseco...
\inmodule QtDBus
Definition qdbuserror.h:21
@ InvalidSignature
Definition qdbuserror.h:43
static void setParametersValidated(QDBusMessage &msg, bool enable)
\inmodule QtDBus
void setInteractiveAuthorizationAllowed(bool enable)
Enables or disables the ALLOW_INTERACTIVE_AUTHORIZATION flag in a message.
void setArguments(const QList< QVariant > &arguments)
Sets the arguments that are going to be sent over D-Bus to arguments.
static QDBusMessage createError(const QString &name, const QString &msg)
Constructs a new DBus message representing an error, with the given name and msg.
static QDBusMessage createMethodCall(const QString &destination, const QString &path, const QString &interface, const QString &method)
Constructs a new DBus message representing a method call.
static bool demarshall(const QDBusArgument &, QMetaType id, void *data)
static const char * typeToSignature(QMetaType type)
\inmodule QtDBus
static QDBusPendingCall fromError(const QDBusError &error)
The QDBusServiceWatcher class allows the user to watch for a bus service change.
\inmodule QtDBus
QVariant variant() const
Returns this D-Bus variant as a QVariant object.
void reserve(qsizetype size)
Definition qlist.h:753
void append(parameter_type t)
Definition qlist.h:458
\inmodule QtCore
Definition qmetaobject.h:19
static QMetaMethod fromSignal(PointerToMemberFunction signal)
const char * tag() const
Returns the tag associated with this method.
MethodType methodType() const
Returns the type of this method (signal, slot, or method).
QByteArray name() const
\inmodule QtCore
\inmodule QtCore
Definition qmetatype.h:341
void destruct(void *data) const
void * construct(void *where, const void *copy=nullptr) const
friend class QVariant
Definition qmetatype.h:796
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
QThread * thread() const
Returns the thread in which the object lives.
Definition qobject.cpp:1598
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
static QThread * currentThread()
Definition qthread.cpp:1039
\inmodule QtCore
Definition qvariant.h:65
#define DBUS_INTERFACE_PROPERTIES
b clear()
auto signal
auto mo
[7]
bool checkInterfaceName(const QString &name, AllowEmptyFlag empty, QDBusError *error)
Definition qdbusutil_p.h:62
QString dbusInterfaceProperties()
bool checkObjectPath(const QString &path, AllowEmptyFlag empty, QDBusError *error)
Definition qdbusutil_p.h:86
@ EmptyNotAllowed
Definition qdbusutil_p.h:59
bool checkBusName(const QString &name, AllowEmptyFlag empty, QDBusError *error)
Definition qdbusutil_p.h:74
QString disconnectedErrorMessage()
CallMode
This enum describes the various ways of placing a function call.
Combined button and popup list for selecting options.
constexpr QBindableInterface iface
Definition qproperty.h:666
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char * interface
DBusConnection const char DBusError * error
DBusConnection * connection
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
static QDBusError checkIfValid(const QString &service, const QString &path, const QString &interface, bool isDynamic, bool isPeer)
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
static ControlElement< T > * ptr(QWidget *widget)
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
GLenum mode
const GLfloat * m
GLuint GLuint end
GLuint object
[3]
GLbitfield GLuint64 timeout
[4]
GLenum type
GLboolean enable
GLuint name
GLsizei const GLchar *const * path
GLfloat GLfloat p
[1]
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
SSL_CTX int void * arg
#define qPrintable(string)
Definition qstring.h:1531
#define QStringLiteral(str)
#define Q_UNUSED(x)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
const char property[13]
Definition qwizard.cpp:101
QList< int > list
[14]
if(qFloatDistance(a, b)<(1<< 7))
[0]
obj metaObject() -> className()
QNetworkReply * reply
args<< 1<< 2;QJSValue threeAgain=fun.call(args);QString fileName="helloworld.qs";QFile scriptFile(fileName);if(!scriptFile.open(QIODevice::ReadOnly)) QTextStream stream(&scriptFile);QString contents=stream.readAll();scriptFile.close();myEngine.evaluate(contents, fileName);myEngine.globalObject().setProperty("myNumber", 123);...QJSValue myNumberPlusOne=myEngine.evaluate("myNumber + 1");QJSValue result=myEngine.evaluate(...);if(result.isError()) qDebug()<< "Uncaught exception at line"<< result.property("lineNumber").toInt()<< ":"<< result.toString();QPushButton *button=new QPushButton;QJSValue scriptButton=myEngine.newQObject(button);myEngine.globalObject().setProperty("button", scriptButton);myEngine.evaluate("button.checkable = true");qDebug()<< scriptButton.property("checkable").toBool();scriptButton.property("show").call();QJSEngine engine;QObject *myQObject=new QObject();myQObject- setProperty)("dynamicProperty", 3)
QJSValueList args
\inmodule QtCore