QThread wird mehrmals aufgerufen/gestartet

Alles rund um die Programmierung mit Qt
Antworten
Ramses94
Beiträge: 3
Registriert: 22. Februar 2018 11:17

QThread wird mehrmals aufgerufen/gestartet

Beitrag von Ramses94 »

Hallo Leute.

Ich habe ein Problem QThreads und ich hoffe Ihr könnt mir helfen.

Ich habe ein Programm mit einer GUI welches am RaspberryPi läuft.
Dieses Programm hat ein GUI welches durchgehend die Serielle Schnittstelle am Pi abhört.
Dieses Durchgehende Abhören habe ich mit einem Thread realisiert. Das abhören selbst wird über WiringPi realisiert.
Funktioniert soweit so gut der Thread wird gestartet und die Daten werden empfangen (qDebug()) und in folge die Signale auch emited.

Jetzt habe ich aber folgendes Problem:
Sobald ich dann das Fenster öffne wo die empfangenen Daten angezeigt werden sollen wird mein thread ein zweites mal gestartet(die Taten also zweimal ausgelesen) wenn ich das Fenster schließe und wieder öffne wird der Thread ein drittes mal gestartet
ich komme einfach nicht dahinter wieso dem so ist bzw wie ich das verhindern kann.


widget.h

Code: Alles auswählen

#ifndef WIDGET_H
#define WIDGET_H

#include "serialread.h"
#include <QWidget>
#include <QThread>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
    Ui::Widget *ui;
    
    serialRead *thread1 = new serialRead();
    bool Stop;
    
protected: 
    void changeEvent(QEvent *e);

public slots:
    void openStart();

};

#endif // WIDGET_H


widget.cpp hier wird der Thread gestartet

Code: Alles auswählen

#include "widget.h"
#include "ui_widget.h"

#include <QDebug>


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    workerRead->moveToThread(threadRead);  
    thread1->start();
    connect(ui->pushButton_3, SIGNAL(clicked()),this, SLOT(openStart()));

}

Widget::~Widget()
{
    delete ui;
}



void Widget::openStart()
{
    startNow *f = new startNow();
    f->showFullScreen();
}


void Widget::changeEvent(QEvent *e)
{
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);

        break;
    default:
        break;

    }
}
serialread.h der Thread

Code: Alles auswählen

#ifndef SERIALREAD_H
#define SERIALREAD_H

#include <QObject>
#include <QThread>



class serialRead : public QThread
{
    Q_OBJECT
public:
    explicit serialRead(QObject *parent=0, bool b = false);

    ~serialRead();

signals:
    void valueChanged(int newValue);
    void isFinished();

public slots:

    void run();
    void exec();
   

public:
    unsigned int firstInput;
    bool Stop;
    int fd;


};

#endif // SERIALREAD_H

serialread.cpp

Code: Alles auswählen

#include "serialread.h"
#include "termios.h"

#include <wiringPi.h>
#include <wiringSerial.h>
#include <QDebug>
#include <QThread>
#include <QMutex>


serialRead::serialRead(QObject *parent, bool b):
    QThread(parent), Stop(b)
{

}

serialRead::~serialRead()
{

}

void serialRead::run()
{

    qDebug()<<"thread gestartet";
       exec();

}

void serialRead::exec()
{

    int count=0;

//öffnen der Seriellen Schnittstelle

    if((fd = serialOpen("/dev/ttyAMA0",115200))<0)
    {
        fprintf(stderr,"Cannot open Serial device: %s\n",strerror(errno));
        //hier eventuell ein popup mit einer Warnung
    }

    if(wiringPiSetup()==-1)
    {
       fprintf(stdout,"Cannot start WiringPi: %s\n",strerror(errno));
    }

//Daten Permanent auslesen
while (1)
{
/* nur zum testen ob der überflüssige thread beendet werden kann
    QMutex mutex;
    mutex.lock();
    if(this->Stop)
    {break;}
    mutex.unlock();
*/


    firstInput =serialGetchar(fd);
qDebug()<<firstInput;
    if( firstInput <= 255)
    {       
            emit valueChanged(firstInput);                     
    }

} //while schleife ende


//wird nie erreicht, just for test
    serialClose(fd);
    emit isFinished();
    qDebug()<<"thread beendet";

}



startnow.h heir sollen dann die Daten angezeigt und aktualisiert werden und genau hier beim aufrufen dieses Fensters passiert es auch dass der thread erneut gestartet wird (ich muss den wert Zwei mal empfangen damit er angezeigt / aktualisiert wird)

Code: Alles auswählen

#ifndef STARTNOW_H
#define STARTNOW_H

#include "widget.h"
#include "serialread.h"
#include <QWidget>


namespace Ui {
class startNow;
}

class startNow : public QWidget
{
    Q_OBJECT


public:
    explicit start(QWidget *parent = 0);
    ~startNow();
    Ui::startNow *ui;
   
   Widget *w = new Widget();
   bool Stop;

private:
    unsigned int value
    
public slots:

    void setValuesNew(int value);

};

#endif // STARTNOW_H

startnow.cpp

Code: Alles auswählen

#include "startnow.h"
#include "ui_startnow.h"

#include <stdio.h>
#include <string.h>
#include <errno.h>



startNow::startNow(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::startNow)
{
    ui->setupUi(this);
    
    connect(w->thread1, SIGNAL(valueChanged(int)), this, SLOT(setValuesNew(int)))

}

startSchweissen::~startSchweissen()
{
    delete ui;
}


void startSchweissen::setValuesNew(int value)
{
    schweissSpannung1=value;
    QString num = QString::number(value)
    ui->label->setText(num);
}



Ich hoffe ich erschlage euch jetzt nicht mit zu viel code :oops: :?
aber ich bin schon ziemlich am Ende mit meinen Ideen.
Falls wirklich alle stricke reißen schreibe ich die Daten in ein File und hol sie mir auch von da wieder...aber dass ist wirklich die aller aller letzte hässliche Lösung die ich um jeden Preis vermeiden will :roll:

Ich währe wirklich sehr dankbar wenn Ihr mir helfen könntet.
Danke

Ps: der Original Code empfängt/verarbeitet wesentlich mehr Daten die ich jetzt der Übersicht halber raus genommen habe also bitte verzeiht sollte irgendwo eine Klammer oder ähnliches fehlen.
Zuletzt geändert von Ramses94 am 23. Februar 2018 07:15, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QThread wird mehrmals aufgerufen/gestartet

Beitrag von Christian81 »

Auch wenn der Code sehr unübersichtlich ist und teilweise nicht zusammenpasst:

Code: Alles auswählen

Widget *w = new Widget();
Hier wird w initialisiert, jedes mal wenn die Klasse instanziiert wird. Der Widget ctor wiederrum startet einen Thread ...
Das Widget wiederum ein startNow - Objekt erzeugt riecht irgendwie nach Rekursion...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ramses94
Beiträge: 3
Registriert: 22. Februar 2018 11:17

Re: QThread wird mehrmals aufgerufen/gestartet

Beitrag von Ramses94 »

Hallo Christian81
Auch wenn der Code sehr unübersichtlich ist und teilweise nicht zusammenpasst:
Danke für den Hinweis ich hab da mal ein bischen aufgeräumt.
Tut mir leid ich starr schon so lange auf den Code dass es mir gar nicht mehr wirklich auffällt :roll:
Hier wird w initialisiert, jedes mal wenn die Klasse instanziiert wird. Der Widget ctor wiederrum startet einen Thread ...
Das Widget wiederum ein startNow - Objekt erzeugt riecht irgendwie nach Rekursion...
Das hier

Code: Alles auswählen

Widget *w = new Widget();
der Thread erneut aufgerufen wird und, wie du sagst, eine Rekursion entsteht habe ich bereits vermutet....aber ich weiß nicht wie ich das umgehen/beheben kann.
ich muss doch eine Instanz auf mein Widget erstellen um über connect auch meine Signale ab zu fangen, oder kann ich das auch anders lösen?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QThread wird mehrmals aufgerufen/gestartet

Beitrag von Christian81 »

Dazu fällt mir eigentlich nur 'Parameterübergabe' ein.
Das was Du da gerade versuchst kann ja in keinem Fall funktionieren - das sind ja zwei völlig unabhängige Instanzen von Widget.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Ramses94
Beiträge: 3
Registriert: 22. Februar 2018 11:17

Re: QThread wird mehrmals aufgerufen/gestartet

Beitrag von Ramses94 »

Sorry bin etwas spät mit der Antwort.

dein Stichwort "Parameterübergabe" hat mit ein Licht aufgehen lassen, dass das was ich da vor habe nicht funktionieren kann.
ich hab mich vorerst aber trozdem für die unsaubere Variante mit den globalen variablen entschieden. (dangerous i know :twisted: :roll: )
vielen Dank erstmal.
Antworten