Skip to content
QtWS25 Last Chance
  • 0 Votes
    22 Posts
    7k Views
    R
    @JKSH This is how I emit the OpenCV mat data: emit processedImage(2, videoFrameOut.ptr(0,0),videoFrameOut.cols, videoFrameOut.rows, videoFrameOut.step); The first parameter is just used to determine which display should draw the image and the rest are dimensions and stride which I think are ok. @SGaist You are correct, I changed the line below to make a copy: displayImage = QImage(imageData, width, height, step, QImage::Format_RGBA8888).copy(0,0,width,height); I think this fixed the issue. I got a couple of crashes in 'memcpy' but that was when loading files a little too quickly. I think most likey resizing the data quickly was the issue. I will do more testing this week and post the results. UPDATE: I did a lot more testing and making a local copy fixed the issue. The issue was that I was modifying the array before it was fully copied and this caused crashes when the array was downsized. I will need to revise the overall structure to make sure everything is done sequentially. Thanks!
  • crash at QThead::wait

    Unsolved General and Desktop crash qthread
    5
    0 Votes
    5 Posts
    1k Views
    T
    @A.A.SEZEN Uhm, I think @J-Hilk is right: sometimes my Thread instance has been destroyed. I have fixed by using checking null before calling it, I don't see the crash anymore.
  • 0 Votes
    13 Posts
    4k Views
    Matthew11M
    OK as @J.Hilk said: @J.Hilk said in Passing custom type pointers between threads via signals and slots cause app to crash: are you by any chance exposing those thread-shared custom types directly to qml? And: @J.Hilk said in Passing custom type pointers between QML and threads via signals and slots cause app to crash: I can only tell you that I always ran into trouble when I tried to access/manipulate c++ threaded stuff (directly)via QML. Indeed that was causing the crashes. The solution is to create a copy of the resource that is sent from QML and then send a copy of that resource to thread. As @J.Hilk suggested Manager object should do the job which is: @Matthew11 said in [Passing custom type pointers between QML and threads via signals and slots cause app to crash Manager <-> Threads : communicate via signal/slots with QueuedConnection synchronization/locking on the shared resource Manager <-> QML signals and slots or directly from the manager's memory Below you can find my working example. This is very similar to the code which I provided in the first post. You send a dispatch from QML to specific Contractor, Contractor then is doing his job and return the result back to QML (sends task with input data scenario). Or you send a dispatch to Contractor to retrieve some data (send task with no input data scenario). ContractorTask is no longer exposed to QML. But pointers are no longer send however it is possible in the C++ domain (across main (Manager) and workers threads with proper locking/synchronization). If you want to feel how it is when app is crashing uncomment the line _taskCopy.setData(_data); from pushTaskToContractor() in Controller.h which disabling the step of making the copy of the resource. Thank you all for your help in solving the problem! Code: //.pro QT += quick CONFIG += c++11 SOURCES += \ Contractor.cpp \ main.cpp RESOURCES += qml.qrc HEADERS += \ Contractor.h \ ContractorTask.h \ Controller.h // Contractor.h #ifndef CONTRACTOR_H #define CONTRACTOR_H #include <QObject> #include <ContractorTask.h> class Contractor : public QObject { Q_OBJECT public: Contractor(int _ID, QObject* parent = nullptr); int getID() { return ID; } public slots: void executeTask(ContractorTask _task); signals: void finished(); void taskStarted(ContractorTask _task); void taskFinished(ContractorTask _task); private: int ID; }; #endif // CONTRACTOR_H // Contractor.cpp #include "Contractor.h" #include <QDebug> #include <QThread> Contractor::Contractor(int _ID, QObject *parent) : QObject(parent), ID(_ID) {} void Contractor::executeTask(ContractorTask _task) { emit(taskStarted(_task)); if(getID() != _task.getConctractorID()) { qDebug() << "Not mine ID, discarding"; return; } QVariant localData = _task.getData(); switch(_task.getTaskID()) { case 0: // PASS TASK TO C++ TO RETRIEVE DATA { QList<QVariant> _params; _params.append(12.5F); _params.append(14.36F); QVariant _data = _params; _task.setData(_data); qDebug() << "PASS TASK TO C++ TO RETRIEVE DATA"; } break; case 1: // PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML { QList<QVariant> _params; _params = localData.value<QList<QVariant>>(); QList<float> _floats; int counter = 0; for(auto item : _params) { _floats << item.toFloat(); qDebug() << "Getting data in C++ from QML (QList<float>): item =" << counter++ << "value =" << item; } qDebug() << "PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML"; } break; default: { qDebug() << "Oh... I don't have these one :("; } } emit(taskFinished(_task)); } // ContractorTask.h #ifndef CONTRACTORTASK_H #define CONTRACTORTASK_H #include <QVariant> class ContractorTask { public: ContractorTask() : taskID(-1), contractorID(-1), data("") {} int getTaskID() { return taskID; } void setTaskID(int _ID) {taskID = _ID; } int getConctractorID() { return contractorID; } void setContractorID(int _ID) { contractorID = _ID; } QVariant getData() { return data; } void setData(QVariant _data) { data = _data; } private: int taskID; int contractorID; QVariant data; }; Q_DECLARE_METATYPE(ContractorTask) #endif // CONTRACTORTASK_H // Controller.h #ifndef CONTROLLER #define CONTROLLER #include <QObject> #include <QThread> #include <QDebug> #include <Contractor.h> #include <ContractorTask.h> class Controller : public QObject { Q_OBJECT QThread workerThread; public: Controller() { Contractor *worker = new Contractor(0); worker->moveToThread(&workerThread); connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); connect(this, &Controller::startTask, worker, &Contractor::executeTask); connect(worker, &Contractor::taskStarted, this, &Controller::contractorStartedTask); connect(worker, &Contractor::taskFinished, this, &Controller::contractorFinishedTask); workerThread.start(); } ~Controller() { workerThread.quit(); workerThread.wait(); } signals: void startTask(ContractorTask); void taskStarted(int id, int contractor, QVariant data); void taskEnded(int id, int contractor, QVariant data); public slots: void pushTaskToContractor(int _id, int _contractor, QVariant _data) { // QVariant depends to QML, so make COPY of QVariant CONTENT, before passing it to thread: QList<QVariant> _params; _params = _data.value<QList<QVariant>>(); QVariant _dataToSend = _params; ContractorTask _taskCopy; _taskCopy.setTaskID(_id); _taskCopy.setContractorID(_contractor); _taskCopy.setData(_dataToSend); // Sending local data copy is OK // _taskCopy.setData(_data); // Sending _data (has source in QML) = PROGRAM CRASH!!! emit(startTask(_taskCopy)); } void contractorFinishedTask(ContractorTask _task) { // Passing COPY of ContractorTask to QML: emit(taskEnded(_task.getTaskID(), _task.getConctractorID(), _task.getData())); } void contractorStartedTask(ContractorTask _task) { // Passing COPY of ContractorTask to QML: emit(taskStarted(_task.getTaskID(), _task.getConctractorID(), _task.getData())); } }; #endif // CONTROLLER // main.cpp #include <QGuiApplication> #include <QQmlApplicationEngine> #include <Controller.h> #include <QQmlContext> int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); Controller TaskController; qRegisterMetaType<ContractorTask>(); QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("TaskController", &TaskController); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); // Get item from QML, and connect it's signal (startTaskFromQML) to Controller QObject *item = engine.rootObjects().first(); QObject::connect(item, SIGNAL(startTaskFromQML(int, int, QVariant)), &TaskController, SLOT(pushTaskToContractor(int, int, QVariant))); return app.exec(); } // main.qml import QtQuick 2.12 import QtQuick.Controls 2.5 ApplicationWindow { id: root visible: true width: 640 height: 480 title: qsTr("Test") signal startTaskFromQML(int id, int contractor, variant data) property variant _data: 0 Connections { target: TaskController onTaskEnded: console.log("Contractor with ID =", contractor, "finished task with ID = ", id, "and returned result:", data); onTaskStarted: console.log("Contractor with ID =", contractor, "started task with ID = ", id); } Column { id: column anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter Button { id: passAndGet text: qsTr("PASS TASK WITH DATA TO C++ AND GET THE SAME DATA BACK IN QML") anchors.horizontalCenter: parent.horizontalCenter onClicked: { _data= [1.2, 3.4, 5.6, 7.8] for(var i = 0; i < 50; i++) { root.startTaskFromQML(1, 0, _data) } } } Button { id: getData text: qsTr("PASS TASK TO C++ TO RETRIEVE DATA") anchors.horizontalCenter: parent.horizontalCenter onClicked: { _data = 0 root.startTaskFromQML(0, 0, _data) } } } } // qtquickcontrols2.conf [Controls] Style=Material // qml.qrc <RCC> <qresource prefix="/"> <file>main.qml</file> <file>qtquickcontrols2.conf</file> </qresource> </RCC>
  • 0 Votes
    8 Posts
    2k Views
    dheerendraD
    @Yash001 You can three classes & inheritance mechanism as you mentioned. I'm keeping aside the topic of why not to inherit from QThread.
  • 0 Votes
    9 Posts
    1k Views
    DoohamD
    I dont know why, but if I set the conexion between server and client first and then I call the function startSerialPort(), the reading speed is the normal. But this method just works with the first conexion. The second conexion already experiment the decrease of the reading speed. void MyServer::startSerialPort() { mipuerto2 = new MySerialPort; msgRec = new MensajeRecibido; msgSent = new MensajeEnviar; connect(mipuerto2, SIGNAL(msgChanged(QByteArray*)), this, SLOT(getMens(QByteArray*))); connect(mipuerto2, SIGNAL(msgChanged(QByteArray*)), this, SLOT(idMensaje(QByteArray*))); connect(msgSent, SIGNAL(tienesMensaje(QString*)), this, SLOT(setRecibido(QString *))); mipuerto2->openSerialPort(); } qDebug()<<socketDescriptor<<"Connecting... "; socket = new MySocket(socketDescriptor); controlador++; QThread *thread = new QThread; qDebug()<<thread->currentThreadId(); connect(this, SIGNAL(mensChanged(QByteArray*)), socket, SLOT(getMsg(QByteArray*))); connect(socket, SIGNAL(mensajeEnviarSocket(QByteArray*)), this, SLOT(sendMens(QByteArray*))); connect(socket, SIGNAL(disconnected()),thread, SLOT(quit()) ); connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater())); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); connect(thread, SIGNAL(started()), socket, SLOT(funcionamiento())); connect(socket, SIGNAL(disconnected), this, SLOT(desconectar())); socket->moveToThread(thread); thread->start(); if(controlador==1){ startSerialPort(); }else if (controlador>1) { mipuerto2->closeSerialPort(); delete mipuerto2; startSerialPort(); }
  • 0 Votes
    3 Posts
    4k Views
    DoohamD
    @koahnig You were right, changing the pointer this to socket in the connection function of readyRead, it worked. Thanks you
  • 0 Votes
    23 Posts
    6k Views
    DoohamD
    @CP71 Dont worry, you are helpful. I will tried to find the trouble, I know that must be in my Code of the server, because in the first Code that I published in this thread I could do It. And in a simpler Code for just one connection server-client It also worked.
  • Creating QThread from another QThread

    Solved General and Desktop qthread movetothread
    9
    0 Votes
    9 Posts
    3k Views
    C
    @VRonin Thank you, it works perfectly. I thought that ‘this’ could not be called inside a thread.
  • 0 Votes
    4 Posts
    2k Views
    J.HilkJ
    Hi @Md0ngo said in QThread signals|calls to QChart are blocking the GUI: After so much time lost, solved it!! It seemed to be the fault of the default QSeries implementation... Series.append() apparently emit a couple of signals and resize the inner vector which contain the QPoints. This combined to a O(kn²) loop totally messes up the main event loop. It was "as easy" as refractoring the code so the thread builds up a QVector of QPoints, then signals each vector to the chart and it calls to series.replace() instead of append(), that is actually faster and lighter. great that you were able to fix it yourself, and I learned something new and important about QCharts thank you ;-) I was about to give up after trying the moveToThread way without success, but I was lucky enough to get the solution after finding this. So, not a matter of Qthreads after all.. Now I'm wondering whether refracting the code to create a dedicated event-loop was worth it or not. If an actual worker class is now replacing your infinite while loop, that you posted in the op, than yes it is, definitely! Don't forget to set your topic to solved ;-)
  • 0 Votes
    17 Posts
    16k Views
    D
    @dheerendra At this point, we are fairly certain that the problem is in the main thread code. I have uploaded the main thread code in the previous comment. Please suggest any necessary changes that could solve the issue. thank you.
  • QThread:create syntax

    Solved General and Desktop qthread
    3
    0 Votes
    3 Posts
    3k Views
    S
    Perfect !!!! What a group !!! Thanks very much, this save me a lot work !!! This is an awesome new feature and now I can use it. Rick
  • QThread Freezes GUI

    Unsolved Language Bindings pyside2 qthread pyqt5
    2
    0 Votes
    2 Posts
    2k Views
    SGaistS
    Hi, Looks like there's some problem with the PySide 2 implementation. You should check the bug report system to see if it's something known. If not, please consider opening a new report providing your example and as much details as possible about your current setup.
  • 0 Votes
    3 Posts
    2k Views
    L
    I confirm the same observation, that the script runs with PyQt5 (pyqt5 5.15.4) installed via pip and fails when run with PySide2 (PySide2-5.15.2) installed via pip: QObject::moveToThread: Current thread (0x22b951c64b0) is not the object's thread (0x22b951c6c50). Cannot move to target thread (0x22b951c64b0) qt.qpa.plugin: Could not load the Qt platform plugin "windows" in "" even though it was found. This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem. Available platform plugins are: direct2d, minimal, offscreen, webgl, windows. Following the advice of this thread (https://forum.qt.io/topic/93085/qt-python-development-pyside2/6), I removed the PySide2 installed via pip and installed the version via conda-forge (v 5.13.2) and was able to run the script. So, it appears a matter of packaging/dependencies rather than a strict inability for PySide2 to handle it or something related to the version.
  • 0 Votes
    8 Posts
    4k Views
    VRoninV
    I agree you need to use a state machine for that case. http://doc.qt.io/qt-5/qstatemachine.html probably helps putting down the skeleton already
  • Issue with QThread subclass and signal/slots

    Solved General and Desktop qthread
    21
    0 Votes
    21 Posts
    4k Views
    Joel BodenmannJ
    Please excuse my late reply. I wanted to think about this a bit. I guess we all agree that the documentation is not wrong. It clearly states that slots are not executed in a separate thread when subclassing QThread. Personally, I also feel like this is not exactly "buried" in the documentation. The main problem I see is that people that start coming across QThread are getting misleaded very easily by those famous blog posts that try to tell you how to do it, and then not to do it like that, but then again, it's apparently fine too. I feel like the a paragraph could be added to the documentation which clearly states when subclassing QThread is needed and when not. Basically a: "Only subclass QThread if .... Which might be followed by a "Things to keep in mind" bullet list which lists the "special properties" or "pitfalls". At the end it really just boils down to the fact that QThread is not a thread but just a thread wrapper. From my personal experience I feel like this is very different from how other frameworks provide threading. Of course I understand that renaming QThread is out of the question but I feel like some very generic information paragraph in form of a bullet list might help a lot.
  • QThread correct usage

    Unsolved General and Desktop qthread multithread c++
    5
    0 Votes
    5 Posts
    2k Views
    shavS
    Thanks, I will check!
  • 0 Votes
    8 Posts
    5k Views
    Y
    @Buckwheat Thank you documents link. I will read it and trying to make change in my code. thank you @Buckwheat .
  • Strange errors from QThread

    Solved General and Desktop qthread qbackingstore
    6
    0 Votes
    6 Posts
    5k Views
    SolaVitaeS
    I feel like this is a perfect personification of the "came searching for copper but found gold meme", Sometime in the past I acknowledged that modifying UI elements in a secondary thread caused crashes, I even fixed it, then when I moved my project from computer to computer i must have copied an old file or something, and forgot that that was a no-no. But I digress, not only did this thread solve my problem, it also showed me a way to ditch cURL, and rely solely on QT, as well as circumvent the necessity of the threading in the first place, so thank you all for answering my question and more @Buckwheat / @VRonin /@kshegunov
  • QThread struct reponse example ?

    Unsolved General and Desktop qthread struct
    2
    0 Votes
    2 Posts
    800 Views
    kshegunovK
    response is quite different from QImage, so you should start by matching your function prototypes. To that end you should use the Qt5 connect syntax, which is going to throw you a compile-time error for that code, as it justifiably should. I don't understand the rationale between that global variable - response cevap; though, you should explain what prompted you to use it like this.
  • Connect not working with vector of QThreads

    Solved General and Desktop qthread
    4
    0 Votes
    4 Posts
    1k Views
    B
    @VRonin Merci :-)