mirror of
https://github.com/thp/pyotherside.git
synced 2025-01-28 23:52:55 +08:00
Unbox QJSValue from QVariant in the GUI thread to prevent race condition in QML engine
Calling QJSValue::toVariant() can cause QJSValue to call into QML engine. Since we perform this correction from QPythonWriter thread context, we end up calling QML engine from non-GUI thread and causing race conditions and crashes. This change performs the initial unboxing in QPython::call() and passes to QPythonWriter the actual value of QJSValue in QVariant. This fixes issue #36.
This commit is contained in:
parent
5b76536332
commit
1c0be92e41
@ -242,7 +242,17 @@ QPython::call(QVariant func, QVariant args, QJSValue callback)
|
||||
if (!callback.isNull() && !callback.isUndefined() && callback.isCallable()) {
|
||||
cb = new QJSValue(callback);
|
||||
}
|
||||
emit process(func, args, cb);
|
||||
// Unbox QJSValue from QVariant, since QJSValue::toVariant() can cause calls into
|
||||
// QML engine and we don't want that to happen from non-GUI thread
|
||||
QVariantList vl = args.toList();
|
||||
for (int i = 0, c = vl.count(); i < c; ++i) {
|
||||
QVariant &v = vl[i];
|
||||
if (v.userType() == qMetaTypeId<QJSValue>()) {
|
||||
// TODO: Support boxing a QJSValue as reference in Python
|
||||
v = v.value<QJSValue>().toVariant();
|
||||
}
|
||||
}
|
||||
emit process(func, vl, cb);
|
||||
}
|
||||
|
||||
QVariant
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "converter.h"
|
||||
|
||||
#include <QVariant>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <QTime>
|
||||
#include <QDate>
|
||||
@ -29,6 +30,7 @@
|
||||
#include <QJSValue>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QThread>
|
||||
|
||||
class QVariantListBuilder : public ListBuilder<QVariant> {
|
||||
public:
|
||||
@ -150,8 +152,8 @@ class QVariantConverter : public Converter<QVariant> {
|
||||
if (userType == qMetaTypeId<PyObjectRef>()) {
|
||||
return PYOBJECT;
|
||||
} else if (userType == qMetaTypeId<QJSValue>()) {
|
||||
// TODO: Support boxing a QJSValue as reference in Python
|
||||
return type(v.value<QJSValue>().toVariant());
|
||||
Q_ASSERT(QThread::currentThread() == qApp->thread());
|
||||
return type(QVariant());
|
||||
} else {
|
||||
qDebug() << "Cannot convert:" << v;
|
||||
return NONE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user