Доступ к объекту класса Javascript с помощью функции Qt runJavaScript

Поскольку я новичок в javascript / HTML, и недавно я начал проект с использованием Qt QWebEngineView. Некоторое время я застревал, пытаясь найти лучший способ передать данные из программы C ++ в Javascript. Пока что единственный способ отправить данные в программу Javascript - это использовать функцию QWebEnginePage::runJavaScript. Я также заметил, что существует возможность использования QWebChannels описанного здесь, но я предпочитаю QWebEnginePage::runJavaScript из-за его простоты.

Единственная проблема, с которой я до сих пор сталкивался с методом runJavaScript, заключалась в том, что для записи переменной это должно быть определено в файле HTML, я на самом деле не на 100% уверен, что это единственный способ сделать это. но у меня это сработало только так. Мой текущий сценарий выглядит примерно так:

В файле HTML:

...
        <div id="latitude" ></div>
        <div id="longitude"></div>
        <div id="heading" "></div>
...

В файле C ++:

...
     double Latitude = 44.244; Longitude = 10.3; Heading = 90;
     QString jsQuery = QObject::tr(
                "document.getElementById('latitude').innerHTML  =%1; "
                "document.getElementById('longitude').innerHTML =%2; "
                "document.getElementById('heading').innerHTML   =%3;"
                ).arg(Latitude).arg(Longitude).arg(Heading));
     mapWebView->page()->runJavaScript(jsQuery);
...

С такой настройкой я могу записывать переменные на стороне Javascript / HTML из кода C ++. Поскольку с помощью этого решения мне нужно создать столько отдельных переменных в файле HTML для каждого значения, которое я хочу отправить, я хотел спросить, можно ли вместо использования отдельных переменных использовать объект класса или объект JavaScript. Я создаю класс с некоторыми методами для записи членов класса, как показано ниже: В файле js:

...
export default class PositionState{
    setPosition(latitude = 0.0, longitude = 0.0, heading = 0.0){
        this.Latitude   = latitude;
        this.Longitude  = longitude;
        this.Heading    = heading;
    }
    getLatitude(){
        return this.Latitude;
    }
    getLongitude(){
        return this.Longitude;
    }
    getHeading(){
        return this.Heading;
    }
}

var obj = new PositionState();
...

С помощью этого решения, если я создаю объект класса PositionState и вызываю функцию obj.setPosition(44,10.45) из файла javascript, члены класса объекта устанавливаются правильно, но если я попробую его из C ++, я получу несколько ошибок.

 double Latitude = 44.244; Longitude = 10.3; Heading = 90;
 Qstring jsQuery = QObject::tr(
                    "obj.setPosition(%1, %2, %3);"
                    ).arg(Latitude).arg(Longitude).arg(Heading));
mapWebView->page()->runJavaScript(jsQuery);

Если только определить obj в файле Javascript, я получаю ошибку js: Uncaught ReferenceError: obj is not defined. И если я определяю переменную в файле HTML с помощью Id="obj" и запускаю тот же сценарий, я получаю сообщение об ошибке js: Uncaught TypeError: obj.setPosition is not a function, ошибка возникает, даже если вместо просто obj.setPosition я использую document.getElementById('obj').setPosition.

Итак, то, что я получаю с моими небольшими знаниями HTML / Javascript, заключается в том, что файл HTML не знает моего определения класса, поэтому не распознает метод setPosition. Итак, мой вопрос в том, есть ли способ из кода C ++ написать объект класса.

Я также попытался использовать объект JavaScript, например var Position = {Latitude: 0, Longitude: 0, Heading: 0}, и из кода C ++ запустить сценарий с QString Position = {Latitude: 40, Longitude: 9, Heading: 20};, но также не смог изменить свойства объекта Position.

Любая помощь будет очень признательна, спасибо.


person Andersen    schedule 06.08.2020    source источник


Ответы (1)


Честно говоря, вы, кажется, слишком усложняете ...

Ваш более простой подход не так прост, как использование QWebChannel для обмена объектами между JS и миром C ++. Кроме того, вы теряете много функциональности, идя другим путем: подключаясь к сигналам Qt в JS, перегрузка методов, чтение и установка свойств непосредственно из JS ...

Просто используйте QWebChannel для регистрации QObjects в QWebEnginePage, загрузите QWebChannel на свою HTML-страницу, настройте соединение и все!

В этой статье есть отличное и простое объяснение (с фрагментами кода) того, как это сделать.

Вам не нужно изобретать велосипед.

person Hineios    schedule 15.10.2020