QT 5.7 QThread running in a QWidget Application

235 Views Asked by At

I have a QWiget Subclass Application, which impelemnts its own logic,gui,build,.. wigdet applications, which should be a connecter for the myo wristband and a Parrot Drone. The Connection to the Drone works fine, the Problem lies with the wristband. I have a class which implements the listener for the wirstband

#include <MyoLibrary/include/myo/myo.hpp>    

class MyoDeviceListener: public myo::DeviceListener
{
public:

   MyoDeviceListener();
   virtual void onArmSync(myo::Myo *myo, uint64_t timestamp, myo::Arm arm, myo::XDirection xDirection, float rotation, myo::WarmupState warmupState) override;
   virtual void onArmUnsync(myo::Myo *myo, uint64_t timestamp) override;
   virtual void onBatteryLevelReceived(myo::Myo *myo, uint64_t timestamp, uint8_t level) override;
   virtual void onPair(myo::Myo *myo, uint64_t timestamp, myo::FirmwareVersion firmwareVersion) override;
   virtual void onUnpair(myo::Myo *myo, uint64_t timestamp)override;
   virtual void onLock(myo::Myo *myo, uint64_t timestamp) override;
   virtual void onUnlock(myo::Myo *myo, uint64_t timestamp) override;
   virtual void onPose(myo::Myo *myo, uint64_t timestamp, myo::Pose pose)override;
strong text

};

and the cpp.

#include "myodevicelistener.h"

#include <qDebug>    


MyoDeviceListener::MyoDeviceListener()
{

}

void MyoDeviceListener:: onArmSync(myo::Myo *myo, uint64_t timestamp, myo::Arm arm, myo::XDirection xDirection, float rotation, myo::WarmupState warmupState)
{    
    qDebug()<<"synced";
}

void MyoDeviceListener::onArmUnsync(myo::Myo *myo, uint64_t timestamp)
{
    qDebug()<<"unsynced";
}

void MyoDeviceListener::onBatteryLevelReceived(myo::Myo *myo, uint64_t timestamp, uint8_t level)
{
     qDebug()<<"battery"<<level;
}

void MyoDeviceListener::onPair(myo::Myo *myo, uint64_t timestamp, myo::FirmwareVersion firmwareVersion)
{
    qDebug()<<"Paired";
}

void MyoDeviceListener::onUnpair(myo::Myo *myo, uint64_t timestamp)
{
    qDebug()<<"unpaired";
}
void MyoDeviceListener::onLock(myo::Myo *myo, uint64_t timestamp)
{
    qDebug()<<"locked";
}

void MyoDeviceListener:: onUnlock(myo::Myo *myo, uint64_t timestamp)
{
    qDebug()<<"unlocked";
}

void MyoDeviceListener::onPose(myo::Myo *myo, uint64_t timestamp, myo::Pose pose)
{    
    switch(pose.type())
    {
    case 1: qDebug()<<"Fist";
        myo->notifyUserAction();
        break;
    case 2: qDebug()<<"Wave in";
        myo->notifyUserAction();
        break;
    case 3: qDebug()<<"Wave out";
        myo->notifyUserAction();
        break;
    case 4: qDebug()<<"Spread Fingers";
        myo->notifyUserAction();
        break;
    }
    myo->unlock(myo->unlockHold);

    if (pose.type()==5)
    {
        qDebug()<<"double tapped";
        qDebug()<<"Lock.";
     myo->lock();
    }
}

to start this I created a method in the mainwindow.cpp

void MainWindow::startMyo()
{

    try
    {
        //Application Identifier muss ein reverse String sein
        myo::Hub hub("com.adcsp.myo");

        qDebug()<<"Verbundenes Myo wird gesucht...";
        myo::Myo* myo =hub.waitForMyo(10000);


        if(!myo)
            {
                qDebug()<<"Myo nicht gefunden.";
            }
         else
            {
                qDebug()<<"Myo wurde gefunden.";
                MyoDeviceListener myoDL;

                hub.addListener(&myoDL);

                while (1)
                {
                    hub.run(1000/20);
                }
            }
    }
    catch(std::exception& e )
    {
        qDebug()<<"error: "<<e.what();
    }

}

Problem is obviously as soon as i call this method the Gui freezes cause of the while loop. The myo connection itself works fine and i get all the gestures i want.

I know i need a Qthread for this, but i failed to understand how this works exactly in my case. i red a lot of this blogs like:

https://conf.qtcon.org/system/attachments/104/original/multithreading-with-qt.pdf?1473018682

https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

Also tried this Running function in Qthread - The application will hang in the end i only get a segmentation fold

and of course the QT Doco. Unfortunatly nothing really works, and iam just confused how to use QThread in a proper way with QT 5.7

I know i need to subclass my Method somehow or just to connect the signals and slot (not sure which one though)

but how exactly can i do this? and how exactly do i have to start the thread in my mainwindow.?

I hope you can give me some tipps

EDIT: After several hours trying and errors it works now with this solution Running function in Qthread - The application will hang

just had to change some things, like removing the QTimer. Ty for the ones who were trying to help me.

1

There are 1 best solutions below

2
On

Your code is terrible. Without more info it is impossible to make your code multithreaded (and why? Stackoverflow is not code writing service). This code will use 100% of CPU core time, but it will work.

void MainWindow::startMyo()
{
    qDebug() << "This aplication is designed to crash.";
    try
    {
        myo::Hub hub("com.adcsp.myo");

        myo::Myo* myo = nullptr;

        while(!myo)
        {
            myo = hub.waitForMyo(1);
            qDebug() << "Application is terrible, shutdown it, please";
            if(rand() % 15 == 0) QCoreApplication::processEvents();
        }
        if(myo)
        {
            MyoDeviceListener myoDL;

            hub.addListener(&myoDL);

            while (1)
            {
                hub.run(1000/20);
                QCoreApplication::processEvents();
            }
        }
    }
    catch(const std::exception& e)
    {
        qDebug()<< "Error, it is not crashing, suffer more, ahahaha: " << e.what();
    }
}