Доступ к объекту класса 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 class и вызовите функцию 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.

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

0 ответов

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

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

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

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

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

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