Seite 1 von 1

[gelöst]QTimer läuft nicht!

Verfasst: 29. Juni 2007 13:03
von butze
hi!

Möchte für einen qwt plot, der später kontiniuerlich Daten bekommen soll einen Daten-generator bauen, der alle paar ms neue Daten in ein QVector schreibt.

Anscheinend wird der QTimer auch ordentlich angeschmissen (isActive gibt true zurück). Aber irgendwie will der keine events schmeißen..

Was hab ich falsch gemacht? Laut QTReferenz müsste das so klappen!?
Sitze nun schon 2 tage an dem Sch.... und komme nicht wirklich vorwärts!

main:

Code: Alles auswählen

int main(int argc, char **argv)
{
    QApplication a(argc, argv);
    Objectcontainer oc;

    
    return a.exec(); 
}
ObjectContainer.h

Code: Alles auswählen

#ifndef _Objectcontainer_H
#define _Objectcontainer_H

#include <QVector>
#include <QObject>

class Objectcontainer :public QObject
{
    Q_OBJECT
public: Objectcontainer();

private:
	QVector<double> yVector;
	QVector<double> xVector;
};
#endif
Objectcontainer.cpp:

Code: Alles auswählen

#include "Objectcontainer.h"
#include "data_generator.h"



//speichert die Vectoren und erzeugt einen data generator und übergibt diesem die vektorenweiter

Objectcontainer::Objectcontainer()
{
		xVector.append(323.4244);
		yVector.append(8578.4244);
		data_generator data_gen(xVector,yVector);
        
        //hier plot erzeugen und vektoren übergeben
}
data_generator.h:

Code: Alles auswählen

#ifndef _data_generator_H
#define _data_generator_H

#include <QVector>
#include <QObject>
#include <QTimer>
#include <QWidget>

      
class data_generator : public QObject
{
	Q_OBJECT
public:
	data_generator(QVector<double> , QVector<double>);
	QTimer *timer;

public slots:
	void timerevent();

private:
    
	double time;
	int timerInterval;
	QVector<double> *yVectorPtr;		
	QVector<double> *xVectorPtr;		
};

#endif
data_generator.cpp:

Code: Alles auswählen

#include "data_generator.h"
#include <qwt_math.h>
#include <iostream>
#include <QTimer>

using namespace std;


//Raptor_data_generator soll die Vektoren vom Objectcontainer annehmen und die 
//Referenzen speichern
data_generator::data_generator(QVector<double> xVec, QVector<double> yVec){
	
	xVectorPtr = &xVec;			
	yVectorPtr = &yVec;			
	
	cout << "adr. von xVec : " << &xVec << "inhalt: " << xVec.at(0) <<"\n";
	cout << "adr. von yVec : " << &yVec << "inhalt: " << yVec.at(0) <<"\n";
	
	cout << "adr. von xVectorPtr : " << xVectorPtr << "inhalt: " << xVectorPtr->at(0) <<"\n";
	cout << "adr. von yVectorPtr : " << yVectorPtr << "inhalt: " << yVectorPtr->at(0) <<"\n";
	
   
	timer = new QTimer(this);

    connect(timer, SIGNAL(timeout()), this, SLOT(timerevent()));
    //timer->setSingleShot(false);
    timerInterval = 500;				//alle 500ms einen neuen Wert!
    timer->setInterval(timerInterval);
    
    time = 0.0;							//vergangeneZeit für x-Achse
    cout <<"Starte Timer" <<"\n";
	timer->start();
	cout <<timer->isActive() <<"\n";
    //bis hier alles klar!
}


void data_generator::timerevent(){	//bei jedem Event:
	double randomValue = (double) rand();
	xVectorPtr->append(time);					
	yVectorPtr->append(randomValue);			
	time += 0.001*timerInterval;			//ms -> sek umrechnen
	cout << "data " << randomValue <<"/ " <<time <<" appended, Vector-Kapazitaet: " << yVectorPtr->capacity() << "anz. der Objekte pro Vek: " <<yVectorPtr->size() <<"\n";
}

jemand eine Idee? ich vermute momentan, dass ich das irgendwie Threaden muss... bin aber nicht sicher. Terminiert der einfach das Programm, bevor der QTimer das erste mal greift? wenn ja wieso?

Verfasst: 29. Juni 2007 13:12
von macman
So lange Du den connect auskommentiert lässt, wird das Signal vom Timer auch nicht ausgewertet.

Re: QTimer läuft nicht!

Verfasst: 29. Juni 2007 13:15
von Volker
butze hat geschrieben:

Code: Alles auswählen

//    connect(timer, SIGNAL(timeout()), this, SLOT(timerevent()));
Warum ist das auskommentiert?

... da war macman schneller :-)

Verfasst: 29. Juni 2007 14:08
von butze
args sorry, hatte das connect mal nach aussen in die Objectcontainer Klasse gepackt. Das hat leider nicht geklappt und ich hab den Kommentar vergessen zu entfernen.

Klappt weiterhin nicht :(

... Hab oben den Code korrigiert.

Verfasst: 29. Juni 2007 14:44
von CaptnChaos
weiss zwar noch nicht warum, aber wenn du beide klassen als pointer initialisierst, sollte der timer starten,aber, bei mir stürzt dann das Programm ab...

Verfasst: 29. Juni 2007 14:48
von CaptnChaos
also so wies aussieht verursachst du durch die Vektor Pointer einen Zugriffsfehler oder etwas in der Art, holst du dier die Vektoren direkt als Pointer, funktioniert bei mir alles einwandfrei.

data_generator.cpp:

Code: Alles auswählen

#include "data_generator.h"
#include <ctime>
//#include <qwt_math.h>



//Raptor_data_generator soll die Vektoren vom Objectcontainer annehmen und die
//Referenzen speichern
data_generator::data_generator(QVector<double> *xVec, QVector<double> *yVec) :QObject(){
   
   xVectorPtr = xVec;         
   yVectorPtr = yVec;         
   srand ( time(NULL) );
  
   
   timer = new QTimer(this);

    connect(timer, SIGNAL(timeout()), this, SLOT(generate()));
    //timer->setSingleShot(false);
    timer->start(500);
   
    _time = 0.0;                     //vergangeneZeit für x-Achse
    qDebug("Timer gestartet, singleShot");
    //bis hier alles klar!
}


void data_generator::generate(){   //bei jedem Event:
	qDebug("Timer");
   double randomValue = (double) rand();
   _time += 0.001*500;         //ms -> sek umrechnen
   xVectorPtr->append(_time);               
   yVectorPtr->append(randomValue);          
   QString labText = "data " +
					 QString::number(randomValue) +
					 "/ " + QString::number(_time) +
					 " appended, Vector-Kapazitaet: " + 
					 QString::number(yVectorPtr->capacity()) + "anz. der Objekte pro Vek: " +
					 QString::number(yVectorPtr->size()) +"\n";
	qDebug(labText.toAscii());
} 
data_generator.h:

Code: Alles auswählen


#ifndef _data_generator_H
#define _data_generator_H

#include <QtCore>
     
class data_generator : public QObject
{
   Q_OBJECT
public:
   data_generator(QVector<double> *xVec, QVector<double> *yVec);
   QTimer *timer;

public slots:
   void generate();

private:
   
   double _time;
   int timerInterval;
   QVector<double> *yVectorPtr;      
   QVector<double> *xVectorPtr;      
};

#endif 

Verfasst: 29. Juni 2007 19:13
von butze
vielen Dank für deine Antwort.

habe es mit deiner Lsg versucht, aber es klappt dennoch noch nicht.
(den Konstrukturaufruf hab ich so angeglichen: data_generator data_gen(&xVector,&yVector); ist doch richtig so?!)

qDebug("Timer gestartet, singleShot"); <<<das spuckt er noch aus, danach blinkt die Konsole nur noch und nichts passiert :(



p.S.. was macht das hier: srand ( time(NULL) ); ?


falls die pro file dafür interessant ist:

Code: Alles auswählen

TEMPLATE = app                  # erstelle QT-Anwendung

TARGET = data_generator         # Name der erstellten *.exe Datei setzen

CONFIG += qt \                  # Compiler soll QT benutzen
          warn _on \            # moeglichst viele Compiler-Meldungen anzeigen
          debug_and_release \   # im debug und release modus compilieren
          console \             # Ausgaben werden von der QApp auf die Console weitergeleitet
          thread \              # aktiviere Threading
          QwtDll \              # Compiler soll QWT benutzen

		  
MOC_DIR = moc                   # speichere Meta-Object-Files in Ordner moc

OBJECTS_DIR = obj               # speichere .o Files im obj Ordner
		  
DEPENDPATH += . save \          # suche hier, um abhaengige .h Dateien aufzuslösen
              %QWTDIR%\include  # (to resolve dependencies)
			  
INCLUDEPATH += . save \         # Pfade , in dem bei #include gesucht wird
               %QWTDIR%\include

win32:QwtDll {                  # aktiviere qwt dll Deklarationen
      DEFINES  += QT_DLL QWT_DLL
}


#input der eigenen Headers
HEADERS += src/Objectcontainer.h \
		   src/data_generator.h 

#input der eigenen Sources
SOURCES += src/main.cpp \
           src/data_generator.cpp \
           src/Objectcontainer.cpp

Verfasst: 29. Juni 2007 21:40
von CaptnChaos
hm, hast du auch data_generator und ObjectContainer als Klassen aufgerufen/initialisiert?
srand(time(NULL));
initialisiert den rand() mechanismus, time(NULL), weill dann immer unterschiedliche Zahlen generiert werden, einfach mal Googlen wenns dich interresiert.

hast dus mal genau mit meiner Implementierung versucht und qDebug ausgelesen?

Verfasst: 30. Juni 2007 10:57
von butze
hey! jetzt klappt es! Vielen dank!

aber noch eine kleine Frage:

ich habe komplett deine Implementierung übernommen. Musste jedoch (wie du sagtest) beim aufrufen der Klassen statt

data_generator data_gen(&xVector,&yVector);

das hier schreiben:
data_generator *data_gen = new data_generator(&xVector,&yVector);


(analog dazu)

Objectcontainer *oc = new Objectcontainer;

statt
Objectcontainer oc;


warum?? wo ist denn der unterschied? das hab ich irgendwie noch nicht ganz begriffen (tut mir leid, wenn ich was "dummes" frage, aber ich lerne erst seit 3 wochen c++ und bin so im Uni-projekt abgabestress, dass ich es wohl nicht richtig machen kann... die erwarten ja auch, dass man nach 1 Woche c++ wie ein guru beherrscht :( )

Verfasst: 30. Juni 2007 11:51
von CaptnChaos
damit habe ich auch ein problem... ich habe zwar schon festgestellt, dass Qt irgendwie Probleme bekommt, wenn man klassen nicht als Pointer initialisiert, aber warum weiss ich auch nicht. ich nehms erstmal so hin...
Ich vermute aber, dass es mit dem Konstrktor zusammenhängt, der ohne Pointer initialisierung nicht richtig ausgeführt wird oder so... ka
Vielleicht kann ja jemand anderes was dazu sagen.
also für drei wochen beherschst du die Sprache aber schon recht gut. da hab ich noch mit normalen std-Programmen rumexperimentiert (aber ich würde nicht behaupten dass es zu meinem Schaden war).

Verfasst: 30. Juni 2007 13:44
von Volker
Eigentlich ist das vollkommen logisch:

Code: Alles auswählen

Objectcontainer::Objectcontainer()
{
      xVector.append(323.4244);
      yVector.append(8578.4244);
      data_generator data_gen(xVector,yVector);
       
        //hier plot erzeugen und vektoren übergeben
}
Erzeugt zwar den data_generator, zerstört ihn aber gleich wieder sobald der Gültigkeitsbereich des Konstruktors verlassen wird. Daher läuft nichts wenn die Qt Event loop mit

Code: Alles auswählen

QApplication a(argc, argv);
    Objectcontainer oc;

   
    return a.exec(); 
gestartet wird.

Verfasst: 30. Juni 2007 22:33
von butze
super erklärungen! danke euch beiden!!