Solved QWebEngineView and threads
-
Hello all,
I created the following class:
#include "webmanager.h" WebManager::WebManager() { } WebManager::~WebManager() { } void WebManager::start(std::string link) { _view = new QWebEngineView(); _view->load(QUrl("http://www.qt.io/")); _view->showFullScreen(); } void WebManager::stop() { _view->close(); } void WebManager::setLink(std::string link) { _view->load(QUrl("http://www.google.be/")); }
First the start() function is called and afterwards a bunch of threads are created, these threads at some point call setLink(...). The problem is that the _view->load(...) in setLink(...) crashes when called from these threads, but it does not crash when called from the main branch.
How can I load a url from these threads? I'm using QT 5.11.1 MSVC2017 64bit. I'm new to Qt, so if there are more elegant solutions please let me know, thank you.
Kind regards,
Thomas -
@Thomas_._ said in QWebEngineView and threads:
How can I load a url from these threads?
Hi @Thomas_-_,
QWebEngineView
and all other widgets are not thread-safe. You must only call their methods from theQApplication
thread.May I ask why you want to use other threads?
-
Hi @JKSH ,
Thank you for your response.
I'm using smartcard readers (NFC technology), multiple readers are connected to the pc and depending on what combination of NFC tags is present on these readers the webpage should change. All of these readers are running on a different thread, when a reader detects an NFC tag it calls the function to change the webpage.
If I cannot use threads, how should I tackle this problem? I was thinking maybe a listener observer pattern (see code below), but I don't think that'll work as the notify(..) will still be called from the threads an thus the alarm(..) function as well. I could maybe create a while(true) loop that constantly checks the value of the link set by the threads, but this doesn't seem a clean solution to me, do you have any recommendations?
class AlarmListener {
public:
AlarmListener(WebManger* model) { _model = model;}
~AlarmListener() {}
void alarm(std::string message) {
_model->setLink(message)
}private:
WebManager* _model;
};class SensorSystem {
std::vector < AlarmListener * > listeners;
public:
void attach(AlarmListener *al) {
listeners.push_back(al);
}
void notify(std::string message) {
for (unsigned int i = 0; i < listeners.size(); i++)
listeners[i]->alarm(message);
}
};Kind regards,
Thomas -
@Thomas_._ First of all, how familiar are you with Signals and Slots? This is the key concept in Qt for letting one thread trigger a method in another thread.
Get started by reading https://doc.qt.io/qt-5/signalsandslots.html
-
@JKSH Thank you for your reply.
I was not familiar with Signals and Slots, thank you for the information, it solved my problem!