Singleton benötigt?

Alles rund um die Programmierung mit Qt
Antworten
taocp
Beiträge: 12
Registriert: 10. Januar 2007 14:03

Singleton benötigt?

Beitrag von taocp »

Hallo mal wieder,
bei meinem kleinen Programm tut sich ein anderes Problemchen auf. Ich habe vier RadioButtons, über die man den Wert für einen Timer angeben kann. Mit einem PushButton ("Start") wird dann der Timer gestartet und die ProgressBar läuft auch wie gewünscht ab.
Jetzt passiert es aber, dass die ProgressBar schneller wird, wenn der Benutzer -- während ein Timer gerade läuft -- mit einer RadioButton Auswahl und dem Start Knopf einen neuen Timer startet. Zwar wird die ProgressBar ordnungsgemäß zurückgesetzt, aber sie läuft immer schneller ab.
Die Vermutung ist, dass immer mehr Timer gestartet werden, die alle den Wert der Klassenvariablen progress erhöhen. Das würde bedeuten ich bräuchte sowas wie ein Singleton meines Timers, oder?!
Der Codeabschnitt sieht wie folgt aus:

Code: Alles auswählen

void Dialog::setProgressBar()
{	
	progress += progressStep;	
	progressBar->setValue(static_cast<int>(progress));
}

void Dialog::startTimer()
{
	// Check which radio button was selected
	if (radioButton_1->isChecked())
		seconds = (timeEdit->time().minute() * 60) + timeEdit->time().second();
	else if (radioButton_2->isChecked())
		seconds = 180;
	else if (radioButton_3->isChecked())
		seconds = 300;
	else if (radioButton_4->isChecked())
		seconds = 420;

	progress = 0; // current progress in percentage
	progressStep = 100.0 / seconds; // how many percent correspond to one second
	
	std::cout << "seconds " << seconds << std::endl;
	std::cout << "progressStep " << progressStep << std::endl;
	
	QTimer *timer = new QTimer(this);
	connect(timer, SIGNAL(timeout()), this, SLOT(setProgressBar()));
	timer->start(1000);
}
Wie würde man da am geschicktesten vorgehen? Müsste man jetzt das Objekt static deklarieren? Wie geht das dann mit dem connect Aufruf? Oder geht das ganze auch einfacher auf anderem Wege?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

QTimer *timer als Member von Dialog.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
taocp
Beiträge: 12
Registriert: 10. Januar 2007 14:03

Beitrag von taocp »

Mmh, also ich hab jetzt

Code: Alles auswählen

QTimer *timer;
in die Klassendeklaration von Dialog genommen und dann im Konstruktor den Wert initialisiert mit

Code: Alles auswählen

timer = new QTimer(this);
Das läuft zwar, aber das Problem besteht weiterhin.
Wie müsste ich vorgehen, wenn ich da mit static arbeiten wollte?
Vielleicht liegt das Problem auch noch woanders geartet ... mal weiter recherchieren ...
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Man sollte den alten schon stoppen und löschen... bzw. in dem Fall muss man ihn wohl gar nicht mehr löschen und kann ihn neu starten!
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
taocp
Beiträge: 12
Registriert: 10. Januar 2007 14:03

Beitrag von taocp »

Ich habe das Problem etwas eingrenzen und ein wenig in den Griff kriegen können. Und zwar setze ich jetzt folgende Abfrage ein:

Code: Alles auswählen

if (timer->timerId() == -1)
	connect(timer, SIGNAL(timeout()), this, SLOT(setProgressBar()));
timer->start(1000);
std::cout << timer->timerId() << " ";
Dadurch läuft das Programm wie gewünscht. Die cout Ausgabe sagt mir allerdings, dass ich mit jedem neuen Drücken des Start Knopfes auch einen neuen Timer mit neuer Id erhalte. Das würde doch aber bedeuten, dass dadurch immer mehr Timer erstellt werden, oder?!
Also irgendwie ist mir das noch nicht so ganz geheuer. Wie kann ich denn genau den Timer, der in Benutzung ist, neu starten -- wie komme ich an diesen Timer ran?
Sorry für diese Noob-Fragen ...

// Edit: Der Code war nicht ideal formatiert
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Ich würde einfach mal in die Doku schauen und ggf. etwas C++ Grundlagen pauken :)

Code: Alles auswählen

if(!m_timer) {
   m_timer = new QTimer(this);
   connect(m_timer, SIGNAL(timeout()), this, SLOT(setProgressBar())); 
} else {
    m_timer->stop();
}
m_timer->start(1000);
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
taocp
Beiträge: 12
Registriert: 10. Januar 2007 14:03

Beitrag von taocp »

Okay, also nur mit Deiner Code-Ersetzung stürzte das Programm ab. Ich habe jetzt in der Headerdatei eine statische Variable deklariert:

Code: Alles auswählen

static QTimer *timer;
und diese dann bei der Implementierung initialisiert:

Code: Alles auswählen

QTimer* Dialog::timer = 0;
Dann funktioniert auch Dein Abschnitt und es wird auch wirklich immer nur ein Timer erzeugt. Komisch finde ich nur, dass sich die TimerId ändert, wenn ich diesen neu lade. Ich sehe nämlich in der Doku nur unter dem Abschnitt "int interval () const", dass sich dadurch die Id ändern soll -- wir verwenden aber hier nur start() und stop().
Das mit C++ ist schon korrekt, bin auch mit sehr guten Büchern eingedeckt, nur muss ich jetzt wieder das nächste halbe Jahr Linux Kernelprogrammierung in C betreiben. Da bleibt erstmal nicht zuviel Zeit für anderes. :(
Aber vielen Dank für Deine geduldige Hilfe.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Lerne bitte C++ !
Was soll das static dort? Hast Du überhaupt eine Ahnung was das macht? Du musst die Varaible natürlich mit NULL initialisieren - sonst steht da irgendwas drin und der check auf !m_timer schlägt fehl.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
lepsai
Beiträge: 573
Registriert: 14. September 2004 21:33
Wohnort: Berlin
Kontaktdaten:

Beitrag von lepsai »

ne geile Disskusion :)
Antworten