Seite 1 von 1
Widget, Main Window, Dialog?
Verfasst: Mittwoch 22. Mai 2013, 09:40
von LenardZill
Moin an alle,
Ich habe grade neu in Pyqt angefangen und frage mich jetzt wo der Unterschied zwischen Widget, Main Window und Dialog ist.
Mit anderen Worten, wann verwende ich was bzw. was sind die vor- nachteile?
Ausserdem möchte ich gerne von einem Fenster ein anderes öffnen.
Ich habe also eine ausgangsdatei "main.py" von der öffne ich das Fenster und warte bis die eingabe getätigt wurde.
Jetzt möchte ich das nächste Fenster öffnen weiß aber nicht wie ich das anstellen sollte.
Danke schonmal für eure Antworten!

Gruß Lenard
PS: Hier einmal wie ich das erste Fenster aufrufe:
Code: Alles auswählen
import sys
from PyQt4 import QtGui, QtCore
from dialog.main import Ui_MainForm as Frm
class Main(QtGui.QWidget, Frm):
def __init__(self, nutzername):
QtGui.QWidget.__init__(self)
self.setupUi(self)
app = QtGui.QApplication(sys.argv)
widget = Main()
widget.show()
sys.exit(app.exec_())
Re: Widget, Main Window, Dialog?
Verfasst: Mittwoch 22. Mai 2013, 10:26
von BlackJack
@LenardZill: Verwendung: `QMainWindow` für das Hauptfenster, `QDialog` für Dialoge, und `QWidget` für Fenster die weder Hauptfenster noch Dialog sind und für die es keine passendere, spezialisierte Klasse gibt. Was die Klassen jeweils bieten und wofür man sie einsetzt steht in der Qt-Dokumentation zu diesen Klassen ziemlich ausführlich beschrieben.
Für Dein Code-Beispiel müsstest Du den Signal/Slot-Mechanismus von Qt verwenden um auf die Benutzereingabe zu reagieren und das nächste Fenster zu öffnen. Also irgendein passendes Signal mit einer Funktion oder Methode verbinden, welche dann das nächste Fenster öffnet.
*So* wird das übrigens nicht funktionieren, denn Dein `Main.__init__()` erwartet ein Argument, welches Du aber beim Aufruf gar nicht übergibst.
Das ``as`` beim Import ist übrigens unschön. Abkürzungen sollte man vermeiden, solange sie nicht allgemein bekannt sind. Ich sehe hier den Sinn auch nicht so ganz. Man kürzt mit ``as`` in ein paar Fällen einen Namen ab, wenn man den wirklich sehr oft benötigt, aber dieses `Frm` wird im weiteren Quelltext nur ein einziges mal verwendet. Da hat man also überhaupt keinen Gewinn von, das man den Quelltext unleserlicher macht.
Mit `PyQt4` würde ich ausserdem keinen generierten Quelltext verwenden. Diese Qt-Anbindung hat ein Modul mit dem Namen `PyQt4.uic` mit dem man die GUI-Daten zur Laufzeit einlesen und in Objekte umwandeln kann. Damit spart man sich den Zwischenschritt der Quelltextgenerierung und auch etwas „Boilerplate”-Quelltext. Dein Quelltext könnte dann ungefähr so aussehen:
Code: Alles auswählen
import sys
from PyQt4 import QtGui, uic
def main():
app = QtGui.QApplication(sys.argv)
widget = uic.loadUi('main_form.ui')
widget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Man kann `loadUi()` auch eine Qt-Klasse (oder eine davon abgeleitete) mitgeben, von der dann ein Exemplar erstellt wird und das UI dann „darin” erstellt wird, um einen ähnlichen Effekt wie den von Deinem Klassenbeispiel zu bekommen.
Re: Widget, Main Window, Dialog?
Verfasst: Mittwoch 22. Mai 2013, 11:38
von LenardZill
Vielen Dank schonmal für die Erklärung und richtigstellung meines Codes.
Zu dem Signal/Slot-Mechanismus hab ich jetzt noch eine frage. Wie bekomme ich jetzt das Signal vom Button abgefangen.
Vorher ging es ja mit:
Code: Alles auswählen
self.connect(self.button, QtCore.SIGNAL('pressed()'), self.openWindow())
Gruß
Lenard
Re: Widget, Main Window, Dialog?
Verfasst: Mittwoch 22. Mai 2013, 12:14
von BlackJack
@LenardZill: *So* ging das vorher nicht, denn als letztes Argument wird etwas aufrufbares erwartet. Du übergibst da aber den *Rückgabewert* von der `openWindow()`-Methode und nicht die Methode *selbst*. Du sollst die ja zu dem Zeitpunkt nicht aufrufen, sondern Qt soll die später aufrufen wenn jemand auf die Schaltfläche klickt.
Heutzutage sollte man ausserdem nicht mehr diese Form des Verbindens verwenden. Die Signale gibt es als Attribute auf den Objekten und die haben eine `connect()`-Methode. Ausserdem würde ich `clicked` und nicht `pressed` verwenden. Das dürfte sich dann eher so verhalten, wie der Benutzer das erwartet.
Wie gesagt, man kann der `loadUi()`-Funktion ein zweites Argument mitgeben, in welches dann die GUI „geladen” wird. Ungetestet:
Code: Alles auswählen
#!/usr/bin/env python
import sys
from PyQt4 import QtGui, uic
class Main(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
uic.loadUi('main_form.ui', self)
# self.connect(self.button, QtCore.SIGNAL('pressed()'), self.openWindow)
self.button.clicked.connect(self.openWindow)
def openWindow(self):
pass
def main():
app = QtGui.QApplication(sys.argv)
widget = Main()
widget.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Re: Widget, Main Window, Dialog?
Verfasst: Donnerstag 23. Mai 2013, 11:37
von LenardZill
Achso, jetzt wird es mir klar.
Hab jetzt alles umgesetzt bekommen, danke.
Aber mein letztes Problem steht noch aus, wie kann ich jetzt einen anderen Dialog öffnen?
Code: Alles auswählen
import sys
import ProdukteGui
from PyQt4 import QtGui, uic
class Main(QtGui.QMainWindow):
def __init__(self):
QtGui.QDialog.__init__(self)
uic.loadUi('ui\main.ui')
self.buttonBestellung.clicked.connect(self.openWindow)
def openWindow(self):
#Hier jetzt ein anderes Fenster oeffnen
produkteGui = ProdukteGui.main
produkteGui.show()
def main():
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Die ProdukteGui ist gleich aufgebaut.
#Gruß Lenard
Re: Widget, Main Window, Dialog?
Verfasst: Donnerstag 23. Mai 2013, 12:32
von BlackJack
@LenardZill: Wenn Du mit gleich aufgebaut meinst die hat auch eine `main()`-Funktion in der ein Exemplar von `QApplication` erstellt und dessen `exec_()`-Methode aufgerufen wird, dann geht das nicht. Lies Dir dazu mal die Beschreibung von `QApplication` in der Qt-Dokumentation durch. Der dritte Absatz ist da sehr deutlich.
Du musst halt von der anderen GUI-Klasse ein Exemplar erstellen und dort die `show()`-Methode drauf aufrufen.
Re: Widget, Main Window, Dialog?
Verfasst: Donnerstag 23. Mai 2013, 13:23
von EmaNymton
Vielleicht wäre es auch sinnvoll, wenn du mal beschreibst, was du genau mit dem "Dialog" bezwecken willst. Ich habe nämlich den Eindruck, dass du QMainWindows, QWidgets und QDialoge durcheinander wirfst.
Qt hat z.B. für Standarddialoge, also z.B. simple Abfragen für Strings, Zahlen, ... schon vorgefertigte Klassen, die man verwenden kann. Da musst du nicht das Rad neu erfinden. Wenn du einen eigenen Dialog brauchst, solltest du, wie BlackJack bereits angedeutet hat, ein Objekt der Klasse QDialog erstellen und die Oberfläche halt deinen Bedürfnissen anpassen.
Re: Widget, Main Window, Dialog?
Verfasst: Donnerstag 23. Mai 2013, 13:49
von LenardZill
@EmaNymton: warscheinlich würfel ich wirklich was durcheinander..
Meine Dialoge sind einfach ein weiteres Fenster was sich öffnet. Bsp. Einstellungen.
Oder nehme ich für soetwas lieber QWidgets?
Re: Widget, Main Window, Dialog?
Verfasst: Donnerstag 23. Mai 2013, 14:08
von BlackJack
@LenardZill: Das kommt halt darauf an ob Du etwas brauchst was die Dialog-Klassen bieten. Ich verweise noch einmal auf die Qt-Dokumentation. Da steht bei `QDialog` ausführlich worin die sich von `QWidget` unterscheiden.
Re: Widget, Main Window, Dialog?
Verfasst: Freitag 24. Mai 2013, 08:27
von LenardZill
So, ich hab mir jetzt die QT Dokumentation zum besten gegeben und hoffe ich hab's nun richtig.
Vielen Dank für den Support euch beiden!.
#Gruß Lenard