Seite 1 von 1

QRadioButton::animateClick()

Verfasst: 31. Juli 2009 13:26
von Whitefurrows
Hallo,

in einem QDialog habe ich alle QRadioButtons mit einem Slot verbunden. Der Code in diesem Solt soll bei bestimmten Voraussetzungen nicht ausgeführt werden, auch wenn er aufgerufen wird. Dazu nutze ich eine bool Variable die ich abfrage.

Das Problem dabei ist, dass die Variable aber gleich true ist, sobald ich QRadioButton::animateClick() aufrufe. Deshalb habe ich noch eine QEventLoop eingebaut um ggf. zu warten bis der Klick ausgeführt wurde, aber leider ohne Erfolg. Hier der Code dazu:

Code: Alles auswählen

bolExecuteSlot = false;
ui.buttonGroup->button( intID )->animateClick();
qApp->processEvents(QEventLoop::AllEvents);
// ...
bolExecuteSlot = true;
Das seltsame ist, wenn ich das ganze mit dem Debugger durchgehe funktioniert es. Sobald der Code normal ausgeführt wird, aber nicht. Wenn ich die QEventLoop nicht verwende funktioniert es auch mit dem Debugger nicht!

Wie kann ich das Problem lösen?

Verfasst: 31. Juli 2009 17:04
von upsala
1. Brauchst du kein processEvents!
2. Brauchst du keine 2. Event-Loop
3. Kann man mit diesem Code nichts weiter anfangen...

Verfasst: 1. August 2009 00:58
von Whitefurrows
Vielen Dank schon einmal. Dann versuche ich es etwas ausführlicher und hoffe auf weitere Hilfe:

Den Dialog rufe ich so auf:

Code: Alles auswählen

AuswahlDialog dialog(this);
dialog.exec();
Das ist der Code zu dem Dialog:
Header-Datei

Code: Alles auswählen

#include <QtGui>
#include <ui_auswahldialog.h>

class Hauptfenster;

class AuswahlDialog : public QDialog{
	Q_OBJECT

public:
	AuswahlDialog( QWidget* parent=0, const char* name=0, Qt::WFlags fl=0);
	~AuswahlDialog();

private:
	Ui::AuswahlDialog ui;
	Hauptfenster *hf;
	bool bolSlotNichtVerarbeiten;
	bool bolSpeichern;
	void datenanzeige();

private slots:
	void speichern();
	void datenauswahl();
};
Source-Datei

Code: Alles auswählen

#include "auswahldialog.h"
#include "hauptfenster.h"

AuswahlDialog::AuswahlDialog( QWidget* parent, const char* name, Qt::WFlags fl)
: QDialog(parent, fl)
{

	ui.setupUi(this);
	bolSpeichern = false;
	hf = reinterpret_cast<Hauptfenster*>(parent);
	
	ui.buttonGroup->setId(ui.rb0, 0);
	ui.buttonGroup->setId(ui.rb1, 1);
	ui.buttonGroup->setId(ui.rb2, 2);
	ui.buttonGroup->setId(ui.rb3, 3);

	QList<QRadioButton *> rbListe= this->findChildren<QRadioButton *>();
	for (int i=0;i<rbListe.size();i++)
	{
		connect(rbListe[i], SIGNAL(clicked()), this, SLOT (datenauswahl()));
	}

	connect(ui.cb1, SIGNAL(activated(int)), this, SLOT(datenauswahl()));
	connect(ui.cb2, SIGNAL(activated(int)), this, SLOT(datenauswahl()));
	connect(ui.sb1, SIGNAL(valueChanged(int)), this, SLOT(datenauswahl()));
	connect(ui.sb2, SIGNAL(valueChanged(int)), this, SLOT(datenauswahl()));
	connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT (speichern()));

	this->datenanzeige();
}

AuswahlDialog::~AuswahlDialog(){}

void AuswahlDialog::datenanzeige()
{
	bolSlotNichtVerarbeiten=true;

	if(hf->Daten["ergebnis"])
	{
		ui.buttonGroup->button((int)hf->Daten["rbID"])->animateClick();
		ui.cb1->setCurrentIndex(hf->Daten["cb1"]);
		ui.cb2->setCurrentIndex(hf->Daten["cb2"]);
		ui.sb1->setValue(hf->Daten["sb1"]);
		ui.sb2->setValue(hf->Daten["sb2"]);
		ui.ergebnis->setText( QString().setNum(hf->Daten["ergebnis"]) );
		qApp->processEvents(QEventLoop::AllEvents);
	}
	else
	{
		bolSlotNichtVerarbeiten=false;
		ui.rb1->animateClick();
	}

	bolSlotNichtVerarbeiten=false;
}

void AuswahlDialog::datenauswahl()
{
	if (bolSlotNichtVerarbeiten)
	{
               return;
        }
	
	float ergebnis;
	int id = ui.buttonGroup->checkedId();

	if(id=0) ergebnis = 43;
	else if (id==1) ergebnis = 87;
	else if (id==2) ergebnis = 12;
	else if (id==3) ergebnis = 19;

	bolSpeichern = true;
	ui.ergebnis->setText(QString().setNum(ergebnis));
}

void AuswahlDialog::speichern()
{
	if( bolSpeichern && ui.buttonGroup->checkedButton() ){
		hf->Daten["rbID"]=ui.buttonGroup->checkedId();
		hf->Daten["cb1"]=ui.cb1->currentIndex();
		hf->Daten["cb2"]=ui.cb1->currentIndex();
		hf->Daten["sb1"]=ui.sb1->value();
		hf->Daten["sb2"]=ui.sb2->value();
		hf->Daten["ergebnis"]=ui.ergebnis->text().toFloat();
	}
}
Wenn ich jetzt die datenanzeige() mit dem Debugger durchgehe springt der Debugger nach qApp->processEvents(QEventLoop::AllEvents); zu zu dem Haltepunkt in datenauswahl() und bolSlotNichtVerarbeiten ist true. Wenn ich jetzt aber nicht mit dem Debugger über qApp->processEvents(QEventLoop::AllEvents); und nur den Haltepunkt in der datenanzeige() habe ist bolSlotNichtVerarbeiten gleich false.

Kann mir jetzt jemand sagen was ich falsch mache bzw. warum es beim Debuggen von qApp->processEvents(QEventLoop::AllEvents); funktioniert und wenn ich da nicht im Einzelschritt Debugge es nicht funktioniert?

Verfasst: 2. August 2009 02:49
von Whitefurrows
Mir ist noch etwas seltsames aufgefallen, nach jeder der folgenden Zeilen in der Funktion datenanzeige():

Code: Alles auswählen

      ui.buttonGroup->button((int)hf->Daten["rbID"])->animateClick(); // für das connect siehe vollständiger Code zuvor
      ui.cb1->setCurrentIndex(hf->Daten["cb1"]);
      ui.cb2->setCurrentIndex(hf->Daten["cb2"]);
      ui.sb1->setValue(hf->Daten["sb1"]);
      ui.sb2->setValue(hf->Daten["sb2"]);
sollte doch eigentlich der Slot datenauswahl() aufgerufen werden, was aber nicht der Fall ist. Hat jemand dafür eine Erklärung?

Der Solt wurden doch mit den Zeilen:

Code: Alles auswählen

   connect(ui.cb1, SIGNAL(activated(int)), this, SLOT(datenauswahl()));
   connect(ui.cb2, SIGNAL(activated(int)), this, SLOT(datenauswahl()));
   connect(ui.sb1, SIGNAL(valueChanged(int)), this, SLOT(datenauswahl()));
   connect(ui.sb2, SIGNAL(valueChanged(int)), this, SLOT(datenauswahl()));
richtig verbunden, oder?

Verfasst: 2. August 2009 08:15
von franzf
Ist immer noch alles recht chaotisch...
Kannst du nicht versuchen das etwas zu reduzieren? So weit dass dein Problem immer noch reproduzierbar ist?
Keiner weiß, was sich hinter deinen ui-Elementen verbrigt. K.A. wie das Element "Daten" ausschaut. USW. Also einfach simples, manuelles Qt, ohne designer etc.

Und wie gesagt ist processEvents() überflüssig, das wird doch sowieso automatisch gemacht, bist ja in der Funktion nicht in ner langen Berechnung, die das schon mal braucht damit die GUI nicht einfriert.

Zu deinem letzten Anliegen:

Code: Alles auswählen

bolSlotNichtVerarbeiten=true;
Na was sagt dir das? Genau, Datenauswahl geht gleich in den return;
processEvents() ist eine normale Funktion. Wenn du die so aufrufst wird die auch gleich abgearbeitet. Und da IMMER zu diesem Zeitpunkt die Variable true ist, wird auch nie datenauswahl in den interessanten Teil springen.

Und das hier im Konstruktor

Code: Alles auswählen

hf = reinterpret_cast<Hauptfenster*>(parent);
braucht es echt nicht! (Les dir mal ne gute Doku zu reinterpret_cast durch)
Du brauchst hier nur nen simplen dynamic_cast.

Verfasst: 2. August 2009 21:24
von Whitefurrows
Erst einmal vielen Dank!

Mh den Code habe ich eigentlich schon auf das wesentliche reduziert, da ich nicht weiß wo der Fehler entsteht! Ich habe mal ein Kleines Beispiel gemacht und angefügt, vielleicht kann mir dann jemand weiterhelfen, obwohl das ganze etwas chaotisch aussieht. Gebe mir ja mühe damit es besser wird!

Was ich seltsam finde, der Dialog wird so erstellt:

Code: Alles auswählen

AuswahlDialog dialog(this);
und nach dem er so angezeigt wird:

Code: Alles auswählen

if (dialog.exec() == QDialog::Accepted)
macht der Debugger einen halt bei datenauswahl(). Das sollte doch eigentlich nicht so sein? Warum passiert es dennoch?

Ja der reinterpret_cast ist natürlich überflüssig und ein dynamic_cast völlig ausreichend. Das war auch nur zum testen!