[Gelöst] Alte Signale löschen bzw. disconnect funktioniert nicht richtig

Alles rund um die Programmierung mit Qt
Antworten
mabralume
Beiträge: 39
Registriert: 26. April 2007 11:54
Wohnort: Siegen
Kontaktdaten:

[Gelöst] Alte Signale löschen bzw. disconnect funktioniert nicht richtig

Beitrag von mabralume » 3. Juli 2018 11:12

Hallo, ich habe folgendes Problem. Ich möchte dynamisch zur Laufzeit ein Toolbar-UnterMenü anlegen und damit ich feststellen kann, welches Action betätigt wurde, benutze ich das Toolbar-Signal "actionTriggered(QAction*)" . Da ich aber im Toolbar-Hauptmenü dieses Signal nicht gebrauchen kann, mache ich ein disconnect beim Schließen des Untermenüs. Wenn ich nun wiederholt im Hauptmenü den Action für das dynamische Untermenü anwähle, dann löst trotzdem sofort das actionTriggered aus, obwohl ich es nur im Untermenü haben möchte bzw. es erst beim Erstellen des Untermenüs conected wird.

Hört sich kompliziert an, ist aber eigentlich recht simpel :

Hauptmenü Toolbar Aufbau:

[1 Menua ^] [2 Menub] [3 Menuc ^] [4 Dynamisch ^]

Die Zahlen sind Shortcuts, Menua und Menuc haben Untermenüs, die in der Toolbar mit nem Pfeil gekennzeichnet und als Popup angezeigt werden.
"Dynamisch" wird folgendermaßen connected :

Code: Alles auswählen


void init()
{
QToolBar* tb_menu = new QToolBar(...);
// Initialisierung Toolbar, QActions aus der Menüleiste werden in die Toolbar 1zu1 übertragen, dann wird die Menüleiste versteckt.

connect(Dynamisch->menuAction(),SIGNAL(triggered(bool)),this,SLOT(slot_setDynamisch(bool)));
}

void slot_setDynamisch(bool)
{
  tb_menu->clear();
  
  for (int i = 0; i<buttonCount;i++)
  { 
    QAction* action = new QAction(this);
    
    action->setText(QString("%1 %2").arg(i+1).arg("Button"); // [1 Button] [2 Button] usw.
    tb_menu->addAction(action);
   }
   QAction* exitAction = new QAction(this); //der Beenden Button um zum Hauptmenü zurückzukehren
   exitAction->setText("0 Beenden");
   
   connect(tb_menu,SIGNAL(actionTriggered(QAction*)),this,SLOT(slot_buttonFilter(QAction*)));
}

In "slot_buttonFilter" will ich feststellen, welche Taste gedrückt wurde, die Nummer ist mir wichtig. Da das Signal actionTriggered sich aber auf die ganze Toolbar bezieht, also auch auf's Hauptmenü, ich da aber den Filter nicht gebrauchen kann, muss ich den Slot disconnecten, sofern das Untermenü "Dynamisch " verlassen wird :

Code: Alles auswählen


void slot_buttonFilter(QAction* button)
{  
    QString number = QString::null;
        
    if(button)
    {
      number = button->text().section(" ",0,0);
    }
    
    if(number.compare("0")!=0)
    {
      printf("Nummer %s\n",number.toLatin1().data());
      //tu was damit !
    }
    else
    {
      disconnect(tb_menu,SIGNAL(actionTriggered(QAction*)),this,SLOT(slot_buttonFilter(QAction*)));
      //Hauptmenü wiederherstellen
     }
}
Was jetzt passiert , Konvention ist "<<" = Eingabe (Mausklick) und ">>" = Ausgabe (printf) :
[1 Menua ^] [2 Menub] [3 Menuc ^] [4 Dynamisch ^]

<< klick [4 Dynamisch]

[1 Button] [2 Button] [3 Button] ... [0 Beenden]

<< klick [2 Button]
>> Nummer 2
<< klick [3 Button]
>> Nummer 3
<< klick [0 Beenden]

[1 Menua ^] [2 Menub] [3 Menuc ^] [4 Dynamisch ^]

<< klick [4 Dynamisch]
>> Nummer 4

[1 Button] [2 Button] [3 Button] ... [0 Beenden]
Die letzte Ausgabe "Nummer 4" ist einfach falsch, weil das Signal über das Hauptmenü kommt und vorher ja über "Beenden" disconnected wurde. Die Ausgaben dürften nur im Untermenü kommen. Wenn ich die anderen Menüpunkte im Hauptmenü aktiviere passiert nix, das disconnect scheint da zu funktionieren, nur wenn ich "Dynamisch" aktiviere, geht sofort das Klick-Signal durch und ruft den Filter auf, obwohl ich noch keine Taste im Untermenü gedrückt habe. Und das passiert aber erst, wenn ich zum 2. Mal auf den Menüpunkt gehe. Beim ersten Aufruf funktioniert es. Das sieht so aus, als ob das Signal eben weiterhin anliegt. Wie kann ich das vorher löschen, bzw. den Zustand wie zum ersten Aufruf wiederherstellen ?

mfg
MB
Zuletzt geändert von mabralume am 4. Juli 2018 11:33, insgesamt 1-mal geändert.
Ein Programmierer ist ein Tool, was Coffein in Code umwandelt.

Christian81
Beiträge: 7281
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Alte Signale löschen bzw. disconnect funktioniert nicht richtig

Beitrag von Christian81 » 3. Juli 2018 18:51

Du kannst doch jede QAction einzeln verbinden - QAction::triggered: http://doc.qt.io/qt-5/qaction.html#triggered
Oder Du merkst Dir die QAction in einem Container und vergleichst bei actionTriggered, welche Action aktiviert wurde. Das würde auch das ständige Neuanlegen mit new überflüssig machen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung

mabralume
Beiträge: 39
Registriert: 26. April 2007 11:54
Wohnort: Siegen
Kontaktdaten:

Re: Alte Signale löschen bzw. disconnect funktioniert nicht richtig

Beitrag von mabralume » 4. Juli 2018 11:25

Hi, danke für Deine Antwort ! :)

Ja, also die Actions im Untermenü ändern sich ja zur Laufzeit, in der Anzahl und im Text, sowie in den Shortcuts. Ich könnte da jetzt vlcht. ne Grundanzahl in einer Liste preallocieren und dann bei Bedarf an die Toolbar übergeben und müßte dann die Eigenschaften anpassen ... naja, so zusätzlichen Verwaltungsaufwand wollt ich halt vermeiden.

Aber die Idee mit dem Actionvergleich von Dir ist gut :idea: . Im triggered wird ja die Action mitgeliefert, wenn ich nun überprüfe, ob die Action eine menuAction() ist und ...

Code: Alles auswählen

void slot_buttonFilter(QAction* button)
{         
    if( button &&
        button!=Dynamisch->menuAction() &&
         Dynamisch->actions().contains(button)  )
         {
            //mach was !
          }
     
     ...
}
Kann ich das Pending Signal rausfiltern. Danke :)

mfg
MB

p.s.:
Trotzdem komisch von Qt, daß das Signal halt immer noch anliegt :shock: (Qt 4.8)
Ein Programmierer ist ein Tool, was Coffein in Code umwandelt.

Antworten