Подтвердить что ты не робот

QByteArray рассматривается как строка в Javascript через QWebChannel

Переход из QtWebKit в QtWebEngine с помощью QWebChannel.

У меня есть invokable функция, которая отправляет объект QVariant в Javascript, который рассматривается как объект JSON. Таким образом, QString становится string, a QInt an int и т.д.

Используя QtWebKit без QWebChannel, QByteArray рассматривался как Uint8ClampedArray, но теперь напрямую преобразован в string с использованием UTF-8 (для чего мой QByteArray не:()

Я сделал что-то не так? Что мне делать?

Вот соответствующая часть кода:

//Qt Window class signal to javascript
void MyWindow::uplink(Response msg)
{
    emit _nativeToJs(msg->toJson());
}



//Response class toJson() method
QVariantMap Response::toJson() const
{
    QVariantMap map;

    map["id"] = m_id; //qulonglong
    map["src"] = QString(m_src);
    map["dst"] = QString(m_dst);
    map["status"] = m_status; //qint16
    map["result"] = m_result; //QVariant, can be a map of string, arrays, etc

    return map;
}


//Javascript 

var foo;
new QWebChannel(qt.webChannelTransport, function(channel) {
    //we connect the signal
    channel.objects.foo._nativeToJs.connect(function(msg){
        //msg is now a JSON object
    });
});

msg.result должен содержать зажатый массив (msgpack data), который я позже декодирую. Теперь у меня есть уродливый string не символ UTF-8, интерпретируемый как UTF-8, с которым я ничего не могу сделать.

4b9b3361

Ответ 1

Не совсем ответ, а начало исследований, так как это очень интересный вопрос.

В версиях Qt < Qt5.6, вы можете найти, как преобразование выполняется путем изучения источников Qt. В частности, я нашел эту функцию в файле C:\Qt\5.5\Src\qtwebkit\Source\WebCore\bridge\qt\qt_runtime.cpp:

JSValueRef convertQVariantToValue(JSContextRef context, PassRefPtr<RootObject> root, const QVariant& variant, JSValueRef *exception)

и этот фрагмент кода внутри него:

if (type == QMetaType::QByteArray) {
    QByteArray qtByteArray = variant.value<QByteArray>();
    WTF::RefPtr<WTF::Uint8ClampedArray> wtfByteArray = WTF::Uint8ClampedArray::createUninitialized(qtByteArray.length());
    memcpy(wtfByteArray->data(), qtByteArray.constData(), qtByteArray.length());
    ExecState* exec = toJS(context);
    APIEntryShim entryShim(exec);
    return toRef(exec, toJS(exec, static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), wtfByteArray.get()));
}

который, по-видимому, является обработкой a QByteArray на стороне JS.

Я также считаю, что, перейдя с Qt WebKit на Qt WebEngine, Qt теперь использует V8, тогда как раньше он был WebCore и JavaScript Core (источник: этот поток). Итак, все могло измениться, но я не знаю, в какой степени.

В настоящий момент я не могу искать дальше в Qt-источниках для Qt5.6, и поэтому я не могу дать реальный ответ, но я надеюсь, что это побудит вас или кого-либо еще изучить его и прояснить это: -).