Seite 1 von 1
Wie auf Objekte der „übergeordneten“ (?) Klasse zugreifen?
Verfasst: Donnerstag 22. August 2013, 09:42
von Hellstorm
Hallo,
ich habe hier ein Qt-Programm in dem ein zweites Fenster geöffnet wird. In dem Hauptfenster habe ich ein Objekt einer Klasse erstellt, auf das ich im zweiten Fenster zugreifen möchte. Nur wie mache ich das am besten?
Stark reduziert hab ich das jetzt so gemacht:
Code: Alles auswählen
class MainWindow(QtGui.QDialog):
def __init__(self):
#...
self.databaseconnection = Database(databasefile)
def openServerDialog(self):
serverwindow = ServerSetup()
serverwindow.show()
class ServerSetup(QtGui.QDialog):
def __init__(self):
pass
Ich möchte jetzt in der ServerSetup-Klasse auf dieses self.databaseconnection zugreifen können. Ich könnte ja einfach
Code: Alles auswählen
def openServerDialog(self):
serverwindow = ServerSetup(self.databaseconnection)
class ServerSetup(QtGui.QDialog):
def __init__(self, databaseconnection):
pass
schreiben. Allerdings frage ich mich, ob es da keine bessere Lösung für gibt, als alle relevanten Objekte zu übergeben?
Danke!
Re: Wie auf Objekte der „übergeordneten“ (?) Klasse zugreife
Verfasst: Donnerstag 22. August 2013, 12:05
von BlackJack
@Hellstorm: Was sollte es denn für eine bessere Lösung geben? Genau wie man bei Funktionen alles was man braucht als Argumente übergibt, macht man das bei Klassen auch.
Was Du allerdings hier „vergessen” hast, ist das Qt-Objekte in der Regel immer ein Elternobjekt übergeben werden sollte, weil Qt sonst mit der Speicherverwaltung durcheinander kommen kann. In sofern müsstest Du dem `ServerSetup()` in `openServerDialog()` sowieso schon mal `self` übergeben und in der `ServerSetup.__init__()` dann auch die QtGui.QDialog.__init__() damit aufrufen.
Re: Wie auf Objekte der „übergeordneten“ (?) Klasse zugreife
Verfasst: Donnerstag 22. August 2013, 13:39
von Hellstorm
Danke für die Antwort!
Mir kam das nur eventuell etwas komisch vor, wenn man von der zweiten Klasse viel in der ursprünglichen Klasse bearbeitet. Da fand ich es ein wenig komisch, wenn man da so viel übergeben müsste. Aber wenn das so normal ist, dann ist es ja in Ordnung.
Zu Qt: Ah, das wusste ich nicht. Danke

Re: Wie auf Objekte der „übergeordneten“ (?) Klasse zugreife
Verfasst: Freitag 23. August 2013, 08:22
von Hellstorm
Hallo noch einmal,
ich wollte nur fragen, ob ich das jetzt so richtig gemacht habe? Funktionieren tut es ja, aber das tut es ja auch oft, selbst wenn es falsch ist
Code: Alles auswählen
class MainWindow(QtGui.QDialog):
def openServerDialog(self):
serverwindow = ServerManager(self, self.databaseconnection)
serverwindow.show()
class ServerManager(QtGui.QDialog):
def __init__(self, parent, database_connection):
QtGui.QDialog.__init__(self, parent)
self.ui = uic.loadUi("ui/server.ui", self)
self.ui.show()
Danke
Achja, brauche ich eigentlich das self.ui.show() in ServerManager.__init__? Oder wo sollte das am besten hinein?
Edit:
Ah, wobei, jetzt hab ich das glaub ich alles ein wenig besser verstanden! Ich kann ja durch Übergabe des Elternobjektes „self“ einfach das gesamte Elternobjekt übergeben und anschließend so auf alle Objekte im Elternobjekt zugreifen, richtig?
Ich habe das jetzt so gemacht:
Code: Alles auswählen
class MainWindow(QtGui.QDialog):
def openServerDialog(self):
serverwindow = ServerManager(self)
serverwindow.show()
class ServerManager(QtGui.QDialog):
def __init__(self, parent):
QtGui.QDialog.__init__(self, parent)
self.ui = uic.loadUi("ui/server.ui", self)
self.database = parent.databaseconnection
Richtig? Also funktionieren tut es.
Re: Wie auf Objekte der „übergeordneten“ (?) Klasse zugreife
Verfasst: Freitag 23. August 2013, 08:49
von BlackJack
@Hellstorm: Ob man das so macht oder lieber die Sachen die man im Kindobjekt (bezogen auf die GUI-Hierarchie) benötigt einzeln übergibt ist Geschmackssache. Was dagegen spricht, ist dass das Kindobjekt dann Annahmen über das übergebene Elternobjekt treffen muss. Und man sieht beim Lesen nicht so einfach *was* alles verwendet wird. Wenn man das explizit übergibt, bekommt man auch einfacher mit wann es anfängt zu viel zu werden und man vielleicht am Entwurf etwas ändern sollte.
Re: Wie auf Objekte der „übergeordneten“ (?) Klasse zugreife
Verfasst: Freitag 23. August 2013, 09:08
von Hellstorm
Ah ok, das erscheint logisch. Na dann werde ich es doch wieder einzeln hineinschreiben. Danke!
Re: Wie auf Objekte der „übergeordneten“ (?) Klasse zugreife
Verfasst: Freitag 23. August 2013, 09:19
von snafu
@Hellstorm: Ich würde - ähnlich wie BlackJack - eher eine Instanziierung mittels `ServerManager(self, self.databaseconnection)` bevorzugen. Ein solches Vorgehen ist flexibler und entkoppelt den `ServerManager` besser vom Eltern-Widget. Spätestens wenn man bei deinem jetzigen Code dieses Detail ordentlich dokumentieren möchte, dann ist es IMHO nämlich blöde zu sagen, dass der `ServerManager` ausschließlich mit Eltern-Widgets umgehen kann, die ein `.databaseconnection`-Attribut haben. Bei einer expliziten Übergabe hingegen erspart man dem Nutzer der `ServerManager`-Klasse nicht nur den Zwang zur fixen Benennung des Attributs vom Eltern-Widget, sondern man fordert nicht mal, dass das übergebene Widget überhaupt eine Datenbank-Verbindung mitbringen muss. Die Verbindung könnte im vorliegenden Beispiel dann theoretisch auch von woanders her als von der `MainWindow()`-Instanz kommen.
Re: Wie auf Objekte der „übergeordneten“ (?) Klasse zugreife
Verfasst: Freitag 23. August 2013, 09:30
von snafu
Zitat aus dem ersten Beitrag:
Hellstorm hat geschrieben:Allerdings frage ich mich, ob es da keine bessere Lösung für gibt, als alle relevanten Objekte zu übergeben?
Naja, bisher sehe ich nur ein einziges zu übergebenes Objekt. Wenn es sehr viele werden, empfiehlt sich immer die Nutzung einer Hilfsklasse wie z.B.
collections.namedtuple, welche die ganzen nötigen Konfigurationsdaten bereitstellt, um möglicherweise "ewig lange" Funktionssignaturen zu vermeiden. Alternativ zu `namedtuple` bietet sich die Verwendung eines `dict()`s an, wo halt dementsprechend aussagekräftige Namen für die einzelnen Konfigurationspunkte als Schlüssel gewählt werden.