Есть ли способ использовать синхронный вызов функции через Qt WebChannel?

В отличие от Qt WebKit BridgeЯ не мог найти использовать синхронный вызов функции на JS side с помощью Qt WebChannel,

Есть ли способ сделать это?

2 ответа

Решение

Я думаю, что нет никакого способа сделать это. В документации сказано: QWebChannel

Обратите внимание, что вся связь между клиентом HTML и сервером QML/C++ является асинхронной.

Более того, в этом блоге точно сказано: преодолеть разрыв между C++/QML и сетью

Но, в отличие от моста WebKit, API, предоставляемый WebChannel, является полностью асинхронным.

Надеюсь, это поможет.

Это не синхронный вызов, но я нашел способ добиться желаемой функциональности без использованияQWebChannelсовсем.

  1. Создайте собственный класс, который наследуется отQWebEnginePage.

  2. ПерегрузитьjavaScriptPrompt(...)метод следующим образом:

            bool MyWebEnginePage::javaScriptPrompt(const QUrl &securityOrigin, const QString &msg, const QString &defaultValue, QString *result) {
        if (msg.length() > 1 && msg[0] == '^') {
            return processCommand(msg, defaultValue, result);
        }
        return QWebEnginePage::javaScriptPrompt(securityOrigin, msg, defaultValue, result);
    }
    
  3. Добавить новый методbool processCommand(QString param1, QString param2, QString* result):

            bool MyWebEnginePage::processCommand(const QString& param1, const QString& param2, QString* result) {
        // parse param1 and/or param2 to determine what to do and get arguments
        char cmd = param1[1].toLatin1();
        if (cmd == '0') {
            // do something or call some method in c++
            QMessageBox::about(0, QString("Test"), QString("It works: ") + param2);
        }
        else if (cmd == '1') {
            // do something or call some method in c++ and return a string
            // the returned string can be encoded JSON object or base64 string
            *result = QString("some string to return: ") + param2;
            return true;
        }
        return false;
    }
    
  4. Назначьте свойMyWebEnginePageкQWebEngineView:

            view->setPage(new MyWebEnginePage());
    
  5. В JavaScript создайте следующий объект:

            bridge = {
        doSomething: function (param) {
            window.prompt('^0', param);
        },
        doSomethingAndReturn: function (param) {
            // if you have more arguments encode them into a single string
            return window.prompt('^1', param);
        }
    };
    
  6. Теперь вы можете синхронно общаться с C++ из JavaScript следующим образом:

            bridge.doSomething('input1');
    var returned_string = bridge.doSomethingAndReturn('input2');
    console.log(returned_string);
    
  7. Исходная функциональность window.prompt все еще работает, но вы не можете использовать^символ в начале сообщения.

Недостаток заключается в том, что если вы хотите передать больше аргументов, вы должны сначала закодировать их все в строку (например, в формате JSON) и декодировать их на C++. Возвращаемое значение может быть закодировано и декодировано таким же образом в объекте моста JavaScript.

Вы также можете перегрузитьjavaScriptConfirmметод, но он может возвращать только логическое значение.

Другие вопросы по тегам