Привожу в порядок один свой старый проект (в том числе портирую с QWebKit на QWebEngine), с тем чтобы опубликовать его на гитхабе.
Проект — wysiwyg редактор на базе html движка в режиме editable.
О том как портировать есть некая информация здесь: https://doc.qt.io/qt-5/qtwebenginewidgets-qtwebkitportingguide.html
Проблема в следующем. Теперь вызовы некоторых функций (в частности runJavaScript) стали асинхронные, и вместо возврата результата они вызывают колбэк, возможно даже в другом потоке — понятия не имею как оно устроено. Хочется минимизировать изменения в коде и по простому превратить это в обычные синхронные вызовы, как раньше.
Т.е. нужно после вызова функции поставить какую-то хрень, которая просто отдает управление операционной системе и ждет события, а колбэк генерирует это событие. После этого хрень возвращает управление и далее функция через обычный return возвращает результат работы колбэка.
Поскольку вся работа локальная (без обращения к сети) то все происходит быстро и никаких тормозов не должно быть; но в идеале хорошо бы туда еще на сякий случай поставить таймаут. Если 10 секунд нет ответа — значит действительно что-то подвисло в движке, и нет смысла ждать дальше.
Что-то вроде:
QVariant WebEditView::execScript(const QString &script)
{
QVariant res;
page()->runJavaScript(script, [&res](const QVariant &result) {
res = result;
GenerateEvent(); //<<< генериурем событие готовности данных
});
WaitForEvent(10000); //<<< ждем 10сек. или до события готовности данных
return res;
}
Здравствуйте, coder9999, Вы писали:
C>Что-то вроде:
C>
QVariant WebEditView::execScript(const QString &script)
C>{
C> WaitForEvent(10000); //<<< ждем 10сек. или до события готовности данных
C> return res;
C>}
Я припоминаю что нечто связанное с processEvents использовал в других проектах, правда там для нестандартной обработки GUI.
Класс назывался QEventLoop. Посмотрел сейчас на доки — кажется подходит. Но проверить пока не могу, куча кода еще не компилируется
Здравствуйте, coder9999, Вы писали:
C>Привожу в порядок один свой старый проект (в том числе портирую с QWebKit на QWebEngine), с тем чтобы опубликовать его на гитхабе. C>Проект — wysiwyg редактор на базе html движка в режиме editable.
C>О том как портировать есть некая информация здесь: https://doc.qt.io/qt-5/qtwebenginewidgets-qtwebkitportingguide.html C>Проблема в следующем. Теперь вызовы некоторых функций (в частности runJavaScript) стали асинхронные, и вместо возврата результата они вызывают колбэк, возможно даже в другом потоке — понятия не имею как оно устроено. Хочется минимизировать изменения в коде и по простому превратить это в обычные синхронные вызовы, как раньше.
Нет, callback будет вызываться в том же потоке, переделка то механическая
C>Т.е. нужно после вызова функции поставить какую-то хрень, которая просто отдает управление операционной системе и ждет события, а колбэк генерирует это событие. После этого хрень возвращает управление и далее функция через обычный return возвращает результат работы колбэка.
C>Поскольку вся работа локальная (без обращения к сети) то все происходит быстро и никаких тормозов не должно быть; но в идеале хорошо бы туда еще на сякий случай поставить таймаут. Если 10 секунд нет ответа — значит действительно что-то подвисло в движке, и нет смысла ждать дальше.
В идеале нужно переписать асинхронно
код приблизительный.
void WebEditView::execScript(const QString &script, const QJSValue& callback )
{
page()->runJavaScript(script, [&res](const QVariant &result) {
callback.call( result );
GenerateEvent(); //<<< генериурем событие готовности данных
});
}
//js Как то так
editView.execScript( "function(){ return 42; }", function(result){ console.log( result ); } );
C>Что конкретно в Qt позволит это сделать?
Можешь еще посмотреть на QMetaObject::invokeMethod + Qt::BlockingQueuedConnection, выполняемый слот в другом потоке вернет управление после завершения и вызывающий код пишется как синхронный, но если метод долгий, ui подвисает и лучше всё таки переписать на асинхронный вариант.
Приблизительно так