PyQt5 - connect slots by name - sinnvoll?

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
pandel
User
Beiträge: 5
Registriert: Mittwoch 11. März 2015, 13:43

Hallo zusammen!

Ich mache mich gerade schlau mit Qt und PyQt5 und hänge bei Model/View gerade am Signal/Slot Thema.

Generell verstehe ich, worum es da geht und auch die verschiedenen Varianten. Mir ist nur nicht ganz klar, wonach ich entscheiden sollte, ob ich es so

Code: Alles auswählen

self.button.clicked.connect(self.blabla)
oder so

Code: Alles auswählen

def on_button_clicked(self)
machen sollte.

Könnte mir vielleicht jemand netterweise veranschaulichen, wo jeweils der Vorteil liegt?

Gefühlsmäßig könnte ich mir folgende Varianten passend dazu vorstellen:
- jeweils eine Klasse für einen View und einen Controller anlegen, den Controller instanzieren
- dann entweder einfach a) den View im Controller instanzieren und nachfolgend sämtliche Verbindungen mit Hilfe der ersten Variante direkt in der Controllerinstanz herstellen
- oder b) den View im Controller instanzieren, jedoch dabei den Controller selbst an den View mit übergeben und dann die Verbindungen in der Viewinstanz mit Hilfe der zweiten Variante herstellen

Bin mir aber nicht recht schlüssig, was die sinnvollere Variante wäre, vielleicht denke ich auch zu kompliziert...

Lieber Gruß
Holger
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Wichtig ist, dass Du überblickst wie das Eventhandling Deiner Anwendung organisiert ist. Mir hilft dabei eine bildliche Vorstellung.

Bei Qt heisst das, von wo nach wo die Signale gehen. Ich finde das Signal-Slot-Konzept sehr anschaulich. Ich stelle mir die Signal- und die Slot-Verbindungen als die Verkabelung eines Geräts vor, das ich zusammenbaue. So ein Kabel kann dabei durchaus von einem Bauteil zum nächsten Bauteil reichen, also vom Viewer zum Controller oder vom Model zum Viewer. Ein Kabel kann auch zur Laufzeit neu hinzukommen oder zur Laufzeit umgesteckt oder deaktiviert werden.

Beim Konzept on_button_clicked bleibe ich innerhalb des gleichen Bauteils, es sind die eingeschränkten GUI-Eventhandling-Möglichkeiten von VB6 oder JavaScript in HTML.
a fool with a tool is still a fool, www.magben.de, YouTube
pandel
User
Beiträge: 5
Registriert: Mittwoch 11. März 2015, 13:43

Erstmal Danke für Deine Antwort! Das kann ich nachvollziehen, auch das mit den Kabeln, so ähnlich stell ich mir das auch vor ;-)

Ob das on_button_clicked Konzept wirklich viel eingeschränkter ist, frage ich mich allerdings, denn wie gesagt, wenn ich im Constructor des Views die aufrufende Instanz als Parameter mitgebe, dann kann ich damit recht easy die Verknüpfung herstellen, das ganze Handling selber aber in der aufrufenden Klasse durchführen. Somit blieb View-bezogener Kremepel im View, Handling aber im Controller.

Ich bekomme es für mich noch nicht hin zu bewerten, ob es einen wirklichen Vorteil (außer Bequemlichkeit natürlich) gibt, die eine oder andere Variante zu nutzen.... einzig die Änderung der Verbindung zur Laufzeit wird wohl bei on_button_clicked nicht so schön einfach gehen, wie bei der anderen Variante. Aber so weit bin ich noch lange nicht, dass ich die Signalverarbeitung quasi on-the-fly ändern müsste. Bei mir geht's um ne GUI mit ein paar Buttons, Feldern und so... somit eher Standardkram.
pandel
User
Beiträge: 5
Registriert: Mittwoch 11. März 2015, 13:43

Fürs Protokoll: ich dachte, ich hätte das mit Signal und Slots einigermaßen gerafft, aber wenn ich mir das hier ansehe

https://github.com/lunaryorn/snippets/b ... rogress.py

dann merke ich, wie weit ich hinterherhinke und wie überhaupt mal gar nicht ich auf die Idee käme, sowas so zu machen. Spannend...
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

pandel hat geschrieben:https://github.com/lunaryorn/snippets/b ... rogress.py
Das Beispiel zeigt Multithreading mit Qt. Wenn Du mit Qt anfängst, dann würde ich eher mit einer Single-Thread GUI anfangen.
a fool with a tool is still a fool, www.magben.de, YouTube
pandel
User
Beiträge: 5
Registriert: Mittwoch 11. März 2015, 13:43

Schon klar :)

Das Beispiel macht aber Signal Slot Kommunikation per se ziemlich deutlich, finde ich. Vor allem, weil es mal einfach was anders ist, als Signal(Button geklickt) -> Slot(Funktion ausführen), was häufig als Beispiel herangezogen wird.

Daneben lerne ich den Kram gerade auch nicht ohne Grund. Ich habe ein relativ umfangreiches Tool in AutoIt geschrieben, was mit den Jahren doch ganz schön voller alter Zöpfe steckt, die ich jetzt mal entwirren will. Da laufen auch einige Sachen, die man wunderbar in eigene Threads auslagern könnte, was sooo ohne weiteres in AutoIt nicht geht (geht schon, is aber, bei dem was ich da drin mache, ziemlich aufwändig), da muss der User momentan eben warten. Das würde ich auch gerne ändern und da kam mir das Beispiel wie gerufen.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@pandel:
Die Autoslots sind vor ein paar Jahren hinzu gekommen, früher gabs diese nicht. Ich nutze Qt schon ziemlich lange und hab sie vorher nicht vermisst und nutze sie auch heute noch nicht. Mir ist in der automatischen Namen-zu-Slot-Auflösung zuviel Magie drin. In C++ spart man damit zwar etwas Schreibarbeit, allerdings handelt man sich eine für mich seltsam anmutende Verquickung von Namen und Logik ein, was gerade beim Refactoring zum Kraus wird. Wobei ich davon ausgehe, dass der QtCreator diese mit beachtet/auflöst.

Multithreading mit Qt ist eine eigene Baustelle, leider wird QThread oft falsch benutzt. Für kleine nebenläufige Aktionen gibts idR was besser geeignetes unter QtConcurrent. Solls wirklich eventgesteuert nebenläufig sein, gehts mit moveToThread() fehlerfreier, als wenn man QThread ableitet. Bei letzterem muss man höllisch aufpassen, in welchem Threadkontext ein QObject erzeugt wurde bzw. lebt. QThread ist halt "nur" eine hübsche Containerklasse für einen Thread und nur innerhalb der run()-Methode ist man im anderen Thread unterwegs.
pandel
User
Beiträge: 5
Registriert: Mittwoch 11. März 2015, 13:43

Danke für die Hinweise! Ich hab mich mittlerweile schon dazu entschieden, das nicht zu verwenden. Die Versuchung, es für einfache Button-klick-mach-was-Zeugs zu nehmen, ist zwar groß, aber ich denke, wenn ich an einer zentralen Stelle alle Signale sauber zuordne, ist das einfach übersichtlicher. Und vor allem auch leichter zu finden, wenn ich mal was suche.

Deine Anmerkunge zu QThread find ich auf jedenfall hilfreich. moveToThread() kannte ich logischerweise noch nicht (sooo weit bin ich ja dann doch noch nicht), aber ich werd's auf jedenfall im Hinterkopf behalten :-)
Antworten