Доступ к объекту класса 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-страницу, настройте соединение и все!
В этой статье есть отличное и простое объяснение (с фрагментами кода) того, как это сделать.
Вам не нужно изобретать велосипед.