Hallo Ihr fleissigen Programmierer,
in meiner Datenbankanwendung habe ich einige Connects erstellt, die bspw. beim Signal 'currentIndexChanged' einer QCombobox oder 'cellChanged' eines QTableWidget Methoden zur Aktualisierung aufrufen. Leider bekomme ich dadurch einige Seiteneffekte wie Mehrfachaufrufe oder Endlosschleifen und habe deshalb eine Methode 'setConnected(bool state)', mit der ich vor jeder Aktion nun alle Events zentral (dis-)connecten kann.
Ich finde diesen Weg nicht sehr elegant, darum meine Frage: Gibt es in Qt so etwas wie 'disconnect.all' und 'connects.restore'? Gibt es Lektüre, wie man das ganze Event-Handling richtig angeht und solche Fallstricke umgeht?
Für ein paar Tipps wäre ich echt dankbar.
Grüße,
Codiac
[gelöst]Signal-Slot-Seiteneffekte
[gelöst]Signal-Slot-Seiteneffekte
Zuletzt geändert von Codiac am 20. November 2013 12:41, insgesamt 1-mal geändert.
Re: Signal-Slot-Seiteneffekte
Hallo,
es wäre mal die Frage zu klären, warum du überhaupt immer alles neu connectest?
Ein Codeausschnitt wäre gut.
mfg
es wäre mal die Frage zu klären, warum du überhaupt immer alles neu connectest?
Ein Codeausschnitt wäre gut.
mfg
Re: Signal-Slot-Seiteneffekte
Wenn du weißt das eine Änderung der Elemente zu einer Signalschleife führt dann musst du gezielt mit blockSignals arbeiten.
Re: Signal-Slot-Seiteneffekte
Aber selbst das würd ich auch unelegant finden ...
Vielleicht versuchst es mal mit einem QTableView und einem eigenen Model drunter .... da hasst viel mehr Kontrolle.
Zumindest bin ich bisher noch nie in die versuchung gekommen, Signal-Slot-Verbindungen temporaer zu deaktivieren
Ciao ...
Vielleicht versuchst es mal mit einem QTableView und einem eigenen Model drunter .... da hasst viel mehr Kontrolle.
Zumindest bin ich bisher noch nie in die versuchung gekommen, Signal-Slot-Verbindungen temporaer zu deaktivieren
Ciao ...
Re: Signal-Slot-Seiteneffekte
Hallo,
um noch eine Beispielsituation anzuhängen:
Ich habe eine QComboBox mit allen Artikeln meiner Applikation. Ändert sich dort der CurrentIndex, wird über ein Signal eine Methode aufgerufen, die zum Artikel passende Infos in einer Tabelle anzeigt. Diese wird beim Befüllen der QComboBox für jeden Eintrag ausgeführt, was ich nicht möchte.
Danke für den Hinweis mit blockSignals, war mir noch nicht bekannt.
Ich habe meine Methode setconnected(bool state) noch etwas erweitert. Sie zählt die Anzahl (dis-)connect-Versuche mit und connected erst wieder, wenn beide Aufrufe gleich oft statt gefunden haben. Damit kann ich verhindern, dass Aufrufe aus Unterfunktionen den Eventhandler zu früh wieder wecken. Ist immer noch nicht so schick, läuft aber ganz gut. (Mein innerer Schweinehund hält mich erstmal von weiteren Überlegungen ab...
). Vielleicht hilft es Jemandem:
Danke jedenfalls für Eure Tipps,
Marcel
um noch eine Beispielsituation anzuhängen:
Ich habe eine QComboBox mit allen Artikeln meiner Applikation. Ändert sich dort der CurrentIndex, wird über ein Signal eine Methode aufgerufen, die zum Artikel passende Infos in einer Tabelle anzeigt. Diese wird beim Befüllen der QComboBox für jeden Eintrag ausgeführt, was ich nicht möchte.
Danke für den Hinweis mit blockSignals, war mir noch nicht bekannt.
Ich habe meine Methode setconnected(bool state) noch etwas erweitert. Sie zählt die Anzahl (dis-)connect-Versuche mit und connected erst wieder, wenn beide Aufrufe gleich oft statt gefunden haben. Damit kann ich verhindern, dass Aufrufe aus Unterfunktionen den Eventhandler zu früh wieder wecken. Ist immer noch nicht so schick, läuft aber ganz gut. (Mein innerer Schweinehund hält mich erstmal von weiteren Überlegungen ab...
Code: Alles auswählen
void quali::setConnected(bool state)
{
static int disCalls = 0; //Anzahl Disconnect-Versuche mitzählen
if(state) //Verbindungen herstellen
{
if(disCalls > 0)
{
disCalls--;
}
if(disCalls == 0)
{
connect(actProtMode,SIGNAL(triggered()),this,SLOT(protChangeShown()));
connect(actProtAdd,SIGNAL(triggered()),this,SLOT(protAdd()));
connect(actProtEdit,SIGNAL(triggered()),this,SLOT(protEdit()));
connect(actProtDel,SIGNAL(triggered()),this,SLOT(protDel()));
connect(actProtOk,SIGNAL(triggered()),this,SLOT(protOk()));
connect(actProtEsc,SIGNAL(triggered()),this,SLOT(protEsc()));
connect(ui->cmbProtArt,SIGNAL(currentIndexChanged(int)),this,SLOT(protRefreshOrders()));
connect(ui->cmbProtOrder,SIGNAL(currentIndexChanged(int)),this,SLOT(protRefreshOrderData()));
...
}
}
else //Verbindungen trennen
{
if(disCalls == 0)
{
disconnect(actProtMode,SIGNAL(triggered()),this,SLOT(protChangeShown()));
disconnect(actProtAdd,SIGNAL(triggered()),this,SLOT(protAdd()));
disconnect(actProtEdit,SIGNAL(triggered()),this,SLOT(protEdit()));
disconnect(actProtDel,SIGNAL(triggered()),this,SLOT(protDel()));
disconnect(actProtOk,SIGNAL(triggered()),this,SLOT(protOk()));
disconnect(actProtEsc,SIGNAL(triggered()),this,SLOT(protEsc()));
disconnect(ui->cmbProtArt,SIGNAL(currentIndexChanged(int)),this,SLOT(protRefreshOrders()));
disconnect(ui->cmbProtOrder,SIGNAL(currentIndexChanged(int)),this,SLOT(protRefreshOrderData()));
...
}
disCalls++;
}
}
Marcel