Seite 1 von 1

Vom ChildWidget aus auf die Methode des ParentWidget zugreifen

Verfasst: Samstag 15. April 2017, 14:07
von Ralf_90
Hallo Python -Forum!

Ich habe mit dem Qt Designer zwei einfache Fenster gebaut: Ein Hauptfentser und ein Dialogfenster. Jetzt will ich, dass das Dialogfenster erscheint, wenn ich im Hauptfenster auf einen button klicke. Das klappt.
Im Dialogfenster gebe ich dann meine Daten ein. Wenn ich nun auf "Verbinden" klicke, soll sich das Dialogfenster schließen und gleichzeitig eine Funktion des Hauptfensters aufrufen und ihr als Parameter meine eingegebenen Daten übergeben.

Leider kann ich nicht auf die Methode des Hauptfensters vom Dialogfenster aus zugreifen.
Kann mir jemand meinen Fehler zeigen?
Ich nutze Python 2.7 und Pyqt4.

Hier einBeispielcode:

Code: Alles auswählen

import sys
import PyQt4.QtCore as core
import PyQt4.QtGui as gui
import PyQt4.uic as uic

class Hauptfenster ():
    
    def __init__(self):
        gui.QMainWindow.__init__(self)
        self.ui = uic.loadUi("Hauptfenster.ui",self)
        
        # Slots:
            
        self.ui.actionVerbinden.triggered.connect(self.clickVerbinden)
        self.ui.buttonBeenden.clicked.connect(self.clickBeenden)
        
        
    def clickBeenden(self):
        self.close()
    
    
    def clickVerbinden(self):
        self.anmeldedialog = AnmeldeDialog()
        self.anmeldedialog.exec_()
    
    def clickSchreiben(self, host, user, pw, db):
        self.anmeldedialog.close()
        print host, user, pw, db
    
        
        
        
class AnmeldeDialog(gui.QDialog):
    
    def __init__(self):
        gui.QDialog.__init__(self)
        self.anm = uic.loadUi("Anmeldedialog.ui",self)
        
        self.host = self.anm.lineHost.text()
        self.user = self.anm.lineUser.text()
        self.pw = self.anm.linePassword.text()
        self.db = self.anm.lineDatabase.text()
        
        
        #Slots:
        
        self.anm.buttonAbbrechen.clicked.connect(self.startAbbrechen)
        self.anm.buttonVerbinden.clicked.connect(self.parent().clickSchreiben(self.host,self.user,self.pw,self.db))
        
    def startAbbrechen():
        self.anm.close()
    
        

def mainfunktion():
    app = gui.QApplication(sys.argv)
    hauptfenster = Hauptfenster()
    hauptfenster.show()
    sys.exit(app.exec_())
    


if __name__ == '__main__':
    mainfunktion()
        

Re: Vom ChildWidget aus auf die Methode des ParentWidget zugreifen

Verfasst: Samstag 15. April 2017, 14:13
von BlackJack
@Ralf_90: Das ist unnötig kompliziert. Das Verbinden würde man im Hauptdialog in der Methode machen die den Anmeldedialog anzeigt nachdem der fertig ist. Also nach dem die `exec_()`-Methode dort zurückkehrt.

Re: Vom ChildWidget aus auf die Methode des ParentWidget zugreifen

Verfasst: Samstag 15. April 2017, 14:23
von Ralf_90
Danke für die Antwort!

Aber wie funktioniert der Aufruf einer Methode einer Klasse aus einer anderen Klasse heraus? Das habe ich leider in keinem Buch gefunden.

Re: Vom ChildWidget aus auf die Methode des ParentWidget zugreifen

Verfasst: Samstag 15. April 2017, 16:23
von BlackJack
@Ralf_90: Das ist ja auch eine komische Frage. Zum ersten ist die Antwort auf diese (falsche) Frage, na man macht das einfach, denn aus einer statischen Methode einer Klasse eine statische Methode einer anderen Klasse aufzurufen ist ja nicht wirklich etwas anderes als eine Funktion aus einer anderen Funktion heraus aufzurufen. Aber das willst Du ja gar nicht, denn hier haben wir ja gar keine statischen Methoden auf Klassen sondern Methoden auf Objekten. Und um eine Methode auf einem Objekt aufzurufen, egal ”von wo” aus, muss man dieses Objekt haben. Objekte/Werte betreten Funktionen und Methoden als Argumente. Also entweder direkt, oder sie sind über Attribute oder Methoden von den Objekten erreichbar die die Methode beim Aufruf übergeben bekommt. Also zum Beispiel existiert das Objekt an `self` gebunden, oder es wird als Argument übergeben, oder man kann es über eine Funktion oder Methode von irgendeinem erreichbaren Objekt abfragen.

Du könntest den Hauptfenster beispielsweise als Argument beim erstellen des Anmeldedialogs übergeben und in der `__init__()` an den Anmeldedialog binden.

Das ist aber in diesem Fall wie schon gesagt der falsche Weg. Wenn sich zwei Objekte gegenseitig kennen müssen, sollte man immer überlegen ob das tatsächlich so sein muss, oder ob die damit nicht zu eng gekoppelt sind. Auf der einen Seite sollte man das hier sowieso machen weil der Dialog gar kein unabhängiges Fenster auf oberster Ebene sein sollte, sondern ein Kind des Hauptfensters und damit auch bei der `QDialog.__init__()` entsprechend angegeben werden sollte. Auf der anderen Seite sollte man *nicht* vom Dialog aufs Hauptfenster zugreifen, auch wenn das dann technisch ginge. Der Dialog sollte nichts über das Fenster wissen müssen. Den sollte man auch von anderen Fenstern aus aufrufen können, oder komplett allein stehend, zum Beispiel bevor das Hauptfenster existiert.

Die Durchführung der Anmeldung sollte von der Methode angestossen werden die auch den modalen Anmeldedialog angezeigt hat.

Re: Vom ChildWidget aus auf die Methode des ParentWidget zugreifen

Verfasst: Samstag 15. April 2017, 17:43
von Ralf_90
Nochmals vielen Dank für deine ausführliche Antwort!

Ich beschäftige mich mit Python erst seit einer Woche, und OOP ist für mich Neuland. Deshalb stelle ich diese blöden Fragen :oops:

Freundliche Grüße