Looks like the SIGNAL loadFinished(bool) is not emitted anymore with Qt 6.8.1
-
Hallo,
I updated from Qt 6.7.2 to Qt 6.8.1.
With the old version my source was running fine under Linux.
Now, after the update, I compiled my source again. There is no error message but it look like a signal is not emitted anymore.
I have lines like this:viewPreview = new QWebEngineView(this); ... connect(viewPreview, SIGNAL(loadFinished(bool)), this, SLOT(printPreviewReadyToStart(bool)));
And the signal should be emitted by this line:
viewPreview->setHtml(updateHTMLprintString(true));
Any idea why this doesn't work anymore with the new Qt version?
Thank you!
-
Work just fine here:
#include "widget.h" #include <QWebEngineView> #include <QVBoxLayout> #include <QDebug> #include <QTimer> Widget::Widget(QWidget *parent) : QWidget(parent) { QVBoxLayout *layout = new QVBoxLayout(this); QWebEngineView *view = new QWebEngineView(this); connect(view, &QWebEngineView::loadFinished, this, &Widget::loadFinished); layout->addWidget(view); QTimer::singleShot(0, [=](){ view->setHtml("<html><head><title>Initial page</title></head><body><p>Initial content</p></body></html>"); } ); QTimer::singleShot(3000, [=](){ view->setHtml("<html><head><title>Three seconds page</title></head><body><p>New content</p></body></html>"); } ); m_elapsedTimer.start(); } Widget::~Widget() {} void Widget::loadFinished(bool ok) { qDebug() << m_elapsedTimer.elapsed() << Q_FUNC_INFO << ok; }
Output:
152 void Widget::loadFinished(bool) true 2961 void Widget::loadFinished(bool) true
-
hmm... Thank you for checking. Did you tried that with Windows or Linux? I am using Linux.
I don't know how to locate the bug:
I wrote this:viewPreview->setHtml(updateHTMLprintString(true)); qDebug("setHtml");
I can see the Debug information in the terminal.
I also wrote this:
void TimetablePrintForm::printPreviewReadyToStart(bool ok){ qDebug("printPreview"); ...
But I can NOT see the debug information in the terminal.
I compiled once again with Qt 6.7.2 and it is working fine. With Qt 6.7.2 I can see it in the terminal and it is working fine.
I compiled again with Qt 6.8.1 and it doesn't work. :-( No "printPreview" debug information in the terminal. The GUI is frozen and I can't click on anything.
I have no idea how I can locate the bug.
-
For my part: Linux, GCC 13, Qt 6.8.1 from online installer
@Volker75 said in Looks like the SIGNAL loadFinished(bool) is not emitted anymore with Qt 6.8.1:
I wrote this:
Where is this in your code? In a constructor, a slot, ...?
Do you see the same issue with my example?
-
@Volker75
Don't know whether this might help or not, but reading this last night it struck me that, assuming it is indeed the case, there might actually be two possible causes. One is that the Qt version does not emit theloadFinished
signal, but the other is that, for whatever reason, the page load itself is not completing or is not recognised as completing in the first place. Maybe put in client-side JS/jQuery code on whatever itsonDocumentReady()
JS event is with a message box or similar to verify that is happening?Having said that, if two other people find it does work on the same Qt version it might be something about your code.
-
Thank you for your answer! Sadly I don't understand "Maybe put in client-side JS/jQuery code on whatever its onDocumentReady() JS event is with a message box or similar to verify that is happening?"
Can you please explain it a bit more detailed? I don't understand what you man with "client-side JS/jQuery code". I only code c++/Qt and html. I don't code JS/jQuery. So I don't know what and where I should do something.
I can't compile your example code.
-
Some more information (see also my answer from 5 minutes ago) about your questions where the code is:
The setHtml stuff is in a functionvoid TimetablePrintForm::print(){ ... viewPreview->setHtml(updateHTMLprintString(true));
The viewPreview = new QWebEngineView(this); is in a constructor:
TimetablePrintForm::TimetablePrintForm(QWidget *parent): QDialog(parent){ ... viewPreview = new QWebEngineView(this);
Hmm... the only difference that I see in the code is, that I am using in the connect() the makros SINGNAL and SLOT, while you coded it without the makros.
The other difference is heap and stack.
I wrote:
viewPreview = new QWebEngineView(this);while you wrote:
QWebEngineView *view = new QWebEngineView(this);So you think it might be because of that?
-
@Volker75
You can inject JavaScript into aQWebEnginePage
via itsrunJavaScript()
method. You can set itsdocument.onReady
to some JS which, say, shows a message box so you know whether it got there. I mentioned this at https://forum.qt.io/post/779514. I don't have the code to hand, but let's not worry about this yet.Your code uses heap, not stack, just as much as the other poster's. You both retrieve a pointer to a
new QWebEngineView(this)
, the only difference is you keep that in (presumably) a member variable. Anyway they are equivalent.I would have said to check whether
connect()
via PMF syntax instead of old-style was the issue, but @hskoglund posted above to say he tried same as yours and it did work for him, so presumably that is not an issue (though you could try the PMF syntax if you wish, I would never use old-style nowadays).Given that
loadFinished()
is not working for you, I would start by connecting the other signals at https://doc.qt.io/qt-6/qwebengineview.html#signals as well. Do you receiveloadStarted()
? What aboutloadProgress()
? You don't getrenderProcessTerminated()
do you? -
I added singals now for loadStarted() and loadProgress() and I wrote functions that print qDebug informations.
With Qt 6.7.2 I can see both!
With Qt 6.8.1 I can't see it. So it also look like the signals for loadStarted and loadProgress are not emitted!
hmm...
I don't understand the problem.
I will try to get rid of the SIGNAL and SLOTS makros and I will try to use a pointer for the viewPreview. But I can't do that now. I must do some other stuff now. I will report later if I was successful or not. -
I just noticed an other thing. Not only the signals are not emitted anymore, I can also see a lot of valgrind warnings if i start my application. But if I start my application, then it is not my fault, since the webview is not in my main dialog. It is only a a sub dialog that i didn't started at that time!
I compiled with debug information -g and i can see that the problem is not in my source. The problem is in the qt webengine source as soon as the Qt library is linked the first time.
There are a lot of warnings like this: Even with this warnings it is working with 6.7.2. But it failed with 6.8.1. So it looks like it is the bug in Qt.Thread 28 Chrome_InProcGpu: ==9401== Conditional jump or move depends on uninitialised value(s) ==9401== at 0xCA6EA0E: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0xCA56BCA: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0xCA59FFA: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0xCA41FB5: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0xCA42698: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0x80318F4: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0x8032635: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0x8035622: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0x8035A9B: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0x8035EBA: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0x80494CA: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2) ==9401== by 0xD4F15D2: ??? (in /home/volker/Qt/6.7.2/gcc_64/lib/libQt6WebEngineCore.so.6.7.2)
-
Ok. Now I done a copy of my project and copy and paste the code above in my project.
I was forced to modify it a bit, because I got errors of unkown widget.h and unknown m_elapsedTimer.My source now looks very very similar to the above one:
TimetablePrintForm::TimetablePrintForm(QWidget *parent): QDialog(parent){ QVBoxLayout *layout = new QVBoxLayout(this); QWebEngineView *view = new QWebEngineView(this); connect(view, &QWebEngineView::loadFinished, this, &TimetablePrintForm::loadFinished); layout->addWidget(view); QTimer::singleShot(0, [=](){ view->setHtml("<html><head><title>Initial page</title></head><body><p>Initial content</p></body></html>"); } ); QTimer::singleShot(3000, [=](){ view->setHtml("<html><head><title>Three seconds page</title></head><body><p>New content</p></body></html>"); } ); } TimetablePrintForm::~TimetablePrintForm() {} void TimetablePrintForm::loadFinished(bool ok) { qDebug() << Q_FUNC_INFO << ok; qDebug("test"); }
Result:
It is working fine with Qt 6.7.2 and it crashes with Qt 6.8.1.
I got:Speicherzugriffsfehler (Speicherabzug geschrieben)
(That is German for "segmentation fault")
I compiled with -g and I didn't get a report about the location in my source. It look like it a segmentation fault in the qtwebengine. (Later added: or maybe in the GPU? see valgrind error log below) -
Additional Information:
I also runned it with Valgrind. Since with valgrind my computer is very slow I was able to see that a dialog opens and closes 2 times for a very short time and then valgrind just do nothing. I can't press anything in my application. It looks like it waiting only.
I was forced to terminate the app.
Last error lines are:==6234== Use of uninitialised value of size 8 ==6234== at 0xCFA3B70: contains (sparse_set.h:227) ==6234== by 0xCFA3B70: re2::DFA::AddToQueue(re2::DFA::Workq*, int, unsigned int) (dfa.cc:867) ==6234== by 0xCFA3E35: re2::DFA::StateToWorkq(re2::DFA::State*, re2::DFA::Workq*) (dfa.cc:828) ==6234== by 0xCFA56B6: re2::DFA::RunStateOnByte(re2::DFA::State*, int) (dfa.cc:1049) ==6234== by 0xCFA7569: RunStateOnByteUnlocked (dfa.cc:1016) ==6234== by 0xCFA7569: bool re2::DFA::InlinedSearchLoop<false, false, true>(re2::DFA::SearchParams*) (dfa.cc:1425) ==6234== by 0xCFA6351: re2::DFA::Search(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, bool, bool, bool, bool*, char const**, re2::SparseSetT<void>*) (dfa.cc:1789) ==6234== by 0xCFA64CC: re2::Prog::SearchDFA(std::basic_string_view<char, std::char_traits<char> >, std::basic_string_view<char, std::char_traits<char> >, re2::Prog::Anchor, re2::Prog::MatchKind, std::basic_string_view<char, std::char_traits<char> >*, bool*, re2::SparseSetT<void>*) (dfa.cc:1886) ==6234== by 0xCF909C9: re2::RE2::Match(std::basic_string_view<char, std::char_traits<char> >, unsigned long, unsigned long, re2::RE2::Anchor, std::basic_string_view<char, std::char_traits<char> >*, int) const (re2.cc:838) ==6234== by 0xCF915E5: re2::RE2::DoMatch(std::basic_string_view<char, std::char_traits<char> >, re2::RE2::Anchor, unsigned long*, re2::RE2::Arg const* const*, int) const (re2.cc:935) ==6234== by 0xCF919E8: re2::RE2::FullMatchN(std::basic_string_view<char, std::char_traits<char> >, re2::RE2 const&, re2::RE2::Arg const* const*, int) (re2.cc:410) ==6234== by 0x81EF5D9: Apply<bool (*)(std::basic_string_view<char>, const re2::RE2&, const re2::RE2::Arg* const*, int), std::basic_string_view<char> > (re2.h:358) ==6234== by 0x81EF5D9: FullMatch<> (re2.h:410) ==6234== by 0x81EF5D9: StringMismatch (gpu_control_list.cc:109) ==6234== by 0x81EF5D9: gpu::(anonymous namespace)::StringMismatch(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*) [clone .part.0] (gpu_control_list.cc:116) ==6234== by 0x81EF8EF: StringMismatch (gpu_control_list.cc:113) ==6234== by 0x81EF8EF: gpu::GpuControlList::GLStrings::Contains(gpu::GPUInfo const&) const (gpu_control_list.cc:328) ==6234== by 0x81F2802: gpu::GpuControlList::Conditions::Contains(gpu::GpuControlList::OsType, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, gpu::GPUInfo const&) const [clone .part.0] (gpu_control_list.cc:555) ==6234== 15 ^C==6234== ==6234== Process terminating with default action of signal 2 (SIGINT) ==6234== at 0x68C74CD: poll (poll.c:29) ==6234== by 0x1356D66D: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0) ==6234== by 0x1350DA52: g_main_context_iteration (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.8000.0) ==6234== by 0x625F91D: QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/volker/Qt6.8/6.8.1/gcc_64/lib/libQt6Core.so.6.8.1) ==6234== by 0x5F92FE1: QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (in /home/volker/Qt6.8/6.8.1/gcc_64/lib/libQt6Core.so.6.8.1) ==6234== by 0x5F8F165: QCoreApplication::exec() (in /home/volker/Qt6.8/6.8.1/gcc_64/lib/libQt6Core.so.6.8.1) ==6234== ==6234== HEAP SUMMARY: ==6234== in use at exit: 25,318,117 bytes in 124,927 blocks ==6234== total heap usage: 931,939 allocs, 807,012 frees, 116,090,981 bytes allocated ==6234== ==6234== LEAK SUMMARY: ==6234== definitely lost: 6,656 bytes in 26 blocks ==6234== indirectly lost: 2,183 bytes in 102 blocks ==6234== possibly lost: 398,168 bytes in 1,186 blocks ==6234== still reachable: 24,911,110 bytes in 123,613 blocks ==6234== of which reachable via heuristic: ==6234== length64 : 203,616 bytes in 1,308 blocks ==6234== newarray : 860,704 bytes in 135 blocks ==6234== multipleinheritance: 16,256 bytes in 56 blocks ==6234== suppressed: 0 bytes in 0 blocks
-
@Volker75 said in Looks like the SIGNAL loadFinished(bool) is not emitted anymore with Qt 6.8.1:
I can't compile his code. Can you give me the .pro file, so that i can compile it?
Here is a version as a single file with PRO file:
# Automatically generated by qmake (3.1) Sun Jan 12 12:12:14 2025 ###################################################################### TEMPLATE = app TARGET = test INCLUDEPATH += . QT += widgets webenginewidgets # You can make your code fail to compile if you use deprecated APIs. # In order to do so, uncomment the following line. # Please consult the documentation of the deprecated API in order to know # how to port your code away from it. # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_UP_TO=0x060000 # disables all APIs deprecated in Qt 6.0.0 and earlier # Input SOURCES += main.cpp
and
main.cpp
:#include <QApplication> #include <QWebEngineView> #include <QDebug> #include <QTimer> #include <QElapsedTimer> class Widget: public QWebEngineView { Q_OBJECT public: explicit Widget(QWidget *parent = nullptr); ~Widget(); private slots: void htmlLoadFinished(bool ok); private: QElapsedTimer m_elapsedTimer; }; Widget::Widget(QWidget *parent): QWebEngineView(parent) { connect(this, &QWebEngineView::loadFinished, this, &Widget::htmlLoadFinished); // or this // connect(this, SIGNAL(loadFinished(bool)), this, SLOT(htmlLoadFinished(bool))); QTimer::singleShot(0, [=](){ this->setHtml("<html><head><title>Initial page</title></head><body><p>Initial content</p></body></html>"); } ); QTimer::singleShot(3000, [=](){ this->setHtml("<html><head><title>Three seconds page</title></head><body><p>New content</p></body></html>"); } ); m_elapsedTimer.start(); } Widget::~Widget() {} void Widget::htmlLoadFinished(bool ok) { qDebug() << m_elapsedTimer.elapsed() << Q_FUNC_INFO << ok; } int main(int argc, char **argv) { QApplication app(argc, argv); Widget widget; widget.resize(800, 600); widget.show(); return app.exec(); } #include "main.moc"