Verwendung von Qt-Signalen und Slots gegen direktes Aufrufen einer Methode

9

Nehmen wir an, ich habe ein Hauptfenster mit einem Schieberegler und einem Widget in diesem Fenster mit einer Methode namens setValue(int) . Ich möchte diese Methode jedes Mal aufrufen, wenn sich der Wert des Schiebereglers geändert hat.

Gibt es einen praktischen Unterschied zwischen den beiden folgenden Wegen, dies zu erreichen:

1

%Vor%

2

%Vor%

Für mich sieht der erste Ansatz besser aus, weil möglicherweise ein Overhead im Zusammenhang mit Signalen und Slots-Mechanismen vermieden wird. Außerdem kann ich value vor dem Senden an widget verarbeiten, wenn ein Bedarf dafür besteht.

Gibt es Szenarien, in denen die zweite Lösung besser ist?

    
jaho 19.02.2014, 23:56
quelle

5 Antworten

1

Der Hauptunterschied in Ihrem Beispiel, ein Signal anstelle eines direkten Anrufs zu verwenden, besteht darin, mehr als einen Listener zuzulassen.

Wenn Sie Ihr Widget setValue () direkt aufrufen, erhält nur dieses eine Widget das C ++ - Signal.

Wenn Sie ein Qt-Signal verwenden, kann jetzt jedes andere Objekt eine Verbindung herstellen, um das Ereignis bei jedem Auftreten zu empfangen.

Wenn Sie nicht voraussehen, dass ein anderes Objekt jemals den Wert per Signal erhalten möchte, würde ich mich nicht damit befassen. Ein direkter Aufruf ist definitiv viel schneller (zwischen 3 und 6 CPU-Anweisungen, anstatt mit Strings zu arbeiten, um Empfänger zu finden!), Aber wie Paranaix erwähnt hat, ist das in einer GUI kein großes Problem (obwohl es in diesem Fall ein Problem werden könnte) ein Problem bei älteren Computern, wenn Sie beim Verschieben der Schieberegler alle diese Signale senden.)

    
Alexis Wilke 20.02.2014, 01:30
quelle
9

Beide Ansätze verwenden Signal-Slot-Verbindungen. Im ersten Fall wird der Aufruf connect von QMetaObject::connectSlotsByName() aufgerufen, der von setupUi aufgerufen wird. Im zweiten Fall rufen Sie explizit connect selbst auf.

Auch ist der erste Ansatz in Qt5 unnötig, wenn C ++ 11 verwendet wird. Sie können den Wert in einem Lambda ändern:

%Vor%

Um vor dem Löschen von ui->widget zu schützen, sollten Sie ein QPointer :

verwenden %Vor%

Der Overhead von Signal-Slot-Verbindungen ist in dieser Antwort quantifiziert .

    
Kuba Ober 20.02.2014 10:43
quelle
4

Vorteile von Signal / Steckplatz:

  • mehrere Slots können mit einem einzelnen Signal verbunden werden, und Sie kümmern sich nicht um das Zuweisen und Freigeben von Speicher für dieses
  • Sie können damit Multithreading umgehen

Signal / Slot-Nachteile:

  • etwas langsamer als Direktanruf
  • deutlich langsamer, wenn der Slot virtuell ist
  • QObject ist ziemlich schwer, also versuchen Sie normalerweise, Milliarden von ihnen zu vermeiden

Weitere Details finden Sie hier

    
Kirill Gamazkov 20.02.2014 15:04
quelle
1

Ich bevorzuge die zweite Methode, da ich zufällig vergessen habe, die "Auto-Connect-Slots" zu löschen, als das UI-Element entfernt wurde, was zu totem Code führte. AFAIK ist das gleiche "hinter der Szene" (schau dir die automatisch erzeugten qt-Dateien an).

Wenn Sie den Wert ändern möchten, würde ich die folgende Methode bevorzugen:

%Vor%

Grütz

    
Robert 20.02.2014 11:00
quelle
0

Signale & amp; Slots ist ein anderer Codierungsstil. Sie können Dinge mit Signalen tun, die nützlich und ordentlich zu traditionellen C ++ funktionieren. Zum Beispiel können Sie const-Signale von const-Funktionen ausgeben und sie mit nicht-const-Slots verbinden lassen (wobei Sie in c ++ keine nichtkonstanten Aufrufe von einer const-Funktion machen können). Ich habe es nie gemocht, veränderbare Objekte zu benutzen, also liefern Signale eine saubere Arbeit für mich.

    
Mike 04.04.2018 18:56
quelle