Seite 1 von 2
Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 13:01
von Robokopp
Hallo
ich habe eine GUI erstellt, in der nun per Klick auf einen Menüeintrag ein neues MainWindow erzeugt werden soll.
Leider bekomm ich es nicht hin..
Hier mal der Quellcode:
Code: Alles auswählen
#!/usr/bin/python
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtGui import QPushButton
import settings
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
#Beschreibung des Hauptfensters
self.resize(800, 400)
self.setWindowTitle(str('HappyBirthday'))
# Funktion 1: Exitbutton
exit = QtGui.QAction('Quit', self)
self.connect(exit, QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()'))
#Oeffnen eines neuen Fensters
self.connect(self.settings,QtCore.SIGNAL('triggered()'),self.openWindow)
def openWindow(self):
self.window2 = settings.Window2()
menubar = self.menuBar()
file = menubar.addMenu('&Options')
file.addAction(settings)
file.addAction("Help")
file.addAction("About")
file.addAction(exit)
#Buttons
newgrp=QtGui.QPushButton(self)
newgrp.setText("New group")
newgrp.setGeometry(100, 300, 150, 100)
edit=QtGui.QPushButton(self)
edit.setText("Edit group")
edit.setGeometry(300, 300, 150, 100)
delgrp=QtGui.QPushButton(self)
delgrp.setText("Delete group")
delgrp.setGeometry(500, 300, 150, 100)
# settings = QtGui.QPushButton(self)
#settings.setText("Settings")
#Label/Textfelder
ueberschrift=QtGui.QLabel(self)
ueberschrift.setText("HappyBirthday")
ueberschrift.setGeometry(300, 40, 200, 30)
font = QtGui.QFont('Serif', 20, QtGui.QFont.Light)
ueberschrift.setFont(font)
app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
Das Fenster soll dann aus dem Script settings.py geladen werden:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
from PyQt4 import QtCore
from PyQt4 import QtGui
class Window2(QtGui.QMainWindow):
def __init__(self,parent=None):
QtGui.QMainWindow.__init__(self,parent)
Dabei erhalte ich immer diesen Fehler:
AttributeError: 'MainWindow' object has no attribute 'settings'
Ich muss mich für das Durcheinander entschuldigen. Habe viel rumprobiert und erstmal die Ordnung außenvor gelassen^^
Kann mir da jemand helfen und gibt es vielleicht noch eine einfachere Möglichkeit, um ein neues Fenster zu erstellen?
MfG
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 13:14
von BlackJack
@Robokopp: Die Ausnahme ist doch auch irgendwie logisch!? Geh mal den Quelltext von `MainWindow.__init__()` durch bis Du zu der Zeile ``self.connect(self.settings...`` kommst und erklär mal wo Deiner Meinung nach das Attribut `settings` herkommen soll!? Das dürfte doch die Zeile sein, auf die Dich der Traceback hinweist, oder? Den könntest Du übrigens das nächste mal auch komplett zeigen. Die Informationen in Tracebacks stehen da nicht zum Spass, sondern um die Quelle von Ausnahmen leichter zu finden.
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 13:52
von Hyperion
Da Du noch die Old-style Methode für connect() verwendest, sei mal der Hinweis auf die schönere New-style Doku angebracht:
http://www.riverbankcomputing.co.uk/sta ... slots.html
Also z.B. aus Deinem Code:
Code: Alles auswählen
# aus
# self.connect(exit, QtCore.SIGNAL('triggered()'), QtCore.SLOT('close()'))
# wird
self.exit.triggered.connect(self.close)
Liest sich doch eleganter, oder?

Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 14:07
von Robokopp
Wo du Recht hast..
aber kannst du mir vielleicht bei meinem eigentlichen Problem lösen?
Ich kriegs nicht gebacken
EDIT:
hab das gerade mal getestet mit der "Neuen Schreibweise"
jetzt erhalte ich folgenden Error:
AttributeError: 'MainWindow' object has no attribute 'exit'
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 14:22
von Hyperion
Robokopp hat geschrieben:
hab das gerade mal getestet mit der "Neuen Schreibweise"
jetzt erhalte ich folgenden Error:
AttributeError: 'MainWindow' object has no attribute 'exit'
Richtig, "exit" ist bei Dir ja ein lokales Attribut. Also ohne "self.", dann sollte es aber klappen.
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 14:27
von Robokopp
Okay
ich hab jetzt das bei "Settings" auch nochmal geändert und bekomme den Fehler AttributeError: 'MainWindow' object has no attribute 'openWindow'
Warum? ich habe openWindow definiert unter MainWindow
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 14:47
von Hyperion
Robokopp hat geschrieben:Okay
ich hab jetzt das bei "Settings" auch nochmal geändert und bekomme den Fehler AttributeError: 'MainWindow' object has no attribute 'openWindow'
Warum? ich habe openWindow definiert unter MainWindow
Du hast eine Funktion openWindow() innerhalb der __init__-Methode Deiner MainWindow-Klasse definiert^1. Die "verschwindet" aber ja nach dem Abarbeiten von init. Was bleibt ist das Attribut self.window2.
^1 Was imho auch ziemlich merkwürdig ist!
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 15:08
von Robokopp
Also ich hab jetzt def openWindow weiter raus gerückt.Jetzt startet das Programm wieder.
Nur leider wurde das Setting Fenster nicht aufgerufen, weshalb ich den Code geändert hab:
Code: Alles auswählen
class Window2(QtGui.QMainWindow):
def __init__(self,parent=None):
QtGui.QMainWindow.__init__(self,parent)
self.resize(800, 400)
self.setWindowTitle(str('Settings'))
app2 = QtGui.QApplication(sys.argv)
set = Window2()
set.show()
sys.exit(app2.exec_())
Wenn ich jetzt mein Hauptprogramm starte, wird nur noch Settings angezeigt....das Hauptfenster nicht.
Danach hab ich "import settings" unter die Methode des Fensteraufrufs geschrieben.
Jetzt wird wieder das Hauptfenster beim Starten angezeigt und wenn ich auf Settings klicke, öffnet sich kurz das Fenster und beide schließen sich wieder.
Danach stürzt Python ab und ich bekomme eine Fehlermeldung von Windows^^
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 15:31
von Hyperion
Also anstatt zu beschreiben, wo Du welchen import hinschreibst, solltest Du (in einem paste-bin wie paste.pocoo.org oder hier im Forum unter dem Logo) den lauffähigen Quellcode mal posten. So muss man sich alles zusammenreimen; unsauber wirkt er auch - die falsche Einrüclung zeigt mir, dass Du da entweder ein wenig schlampig arbeitest oder aber Wissenslücken hast (die viele Leerzeilen sind da auch nicht grad hilfreich; schau Dir doch mal PEP8 genauer an, da werden Empfehlungen zur Anzahl Leerzeilen gegeben).
Was ist eigentlich Dein Ziel? Zwei "QMainWindow" zu haben ist an sich eher ungewöhnlich. Ich würde wage darauf tippen, dass Du einen Dialog öffnen willst und kein neues MainWindow aufmachen möchtest.
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 15:57
von Robokopp
Ich bin Neuling auf dem Gebiet weswegen ich auch geschrieben habe, dass es sehr wirr ist^^
Was ist eigentlich Dein Ziel? Zwei "QMainWindow" zu haben ist an sich eher ungewöhnlich. Ich würde wage darauf tippen, dass Du einen Dialog öffnen willst und kein neues MainWindow aufmachen möchtest.
ich möchte halt lediglich einen neuen Bereich, in dem dann die Einstellungen aufgeführt sind
Mir erscheint das mit dem neuen Mainwindow auch ein bischen komisch, weil ich da dann ja entweder 2 offene Fenster gleichzeitig habe, oder immer eins schließen müsste
Dann werde ich das wohl mit dem Dialog mal versuchen....
Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 16:09
von Hyperion
Also das klingt für mich nach einem Dialog! Schau Dir doch mal in der Doku von Qt die verschiedenen Dialog-Klassen an; vermutlich gibt es da keinen fertigen "QSettingsDialog" passend zu den QSettings, zumindest hab ich in der Doku auf die schnelle keinen gefunden. Aber mit einem Dialog fährst Du richtig imho - zumindest sind bei allen GUI-Programmen, die ich so kenne, Einstellungen immer in Dialogen vorgehalten

Re: Neues Fenster erzeugen
Verfasst: Samstag 12. Februar 2011, 16:31
von Robokopp
Okay vielen Dank für die Info
Dazu hab ich dann gleich noch eine Frage
Dabei wird doch die QMainWindow Klasse behalten und darin dann das Dialogfenster geöffnet oder muss ich dafür dann ein QWidget nehmen?
Re: Neues Fenster erzeugen
Verfasst: Sonntag 13. Februar 2011, 13:39
von Robokopp
Ich brauch nochmal eben Hilfe^^
Ich habe jetzt ein MainWindow mit Menü erzeugt. Der Menüpunkt soll ein QWidget aufrufen.
den Menüpunkt habe ich mit folgendem definiert:
Code: Alles auswählen
settings=QtGui.QMenu("Settings", self)
menubar = self.menuBar
file.addAction(settings)
für das QWidget habe ich diese Methode erstellt:
Code: Alles auswählen
def settings(self):
self.settings = QtGui.QWidget(self)
self.settings.show()
Wie realisiere ich jetzt den Aufruf?
Das hier klappt nicht
Re: Neues Fenster erzeugen
Verfasst: Sonntag 13. Februar 2011, 13:48
von Hyperion
Du musst doch eine QAction erstellen und das triggered Signal dieser Action mit einem Slot verbinden.
Im übrigen bringt es wenig, wenn Du Code-Schnipsel zeigst, die Namen beinhalten, von denen man keine Ahnung hat, welche Objekte an sie gebunden sind. Was ist "file"? (Der Name suggeriert wenig gutes und überschreibt zudem ein built-in, was man vermeiden sollte).
Was bringt die Zeile:
?
Und gibt es einen Grund, wieso Du augenscheinlich nicht eine Dialog-Klasse aufrufst? (Ich gehe mal davon aus, dass ein neues Fenster aufpoppen soll, wie es bisher von Dir ja geschildert wurde im Threadverlauf)
Re: Neues Fenster erzeugen
Verfasst: Sonntag 13. Februar 2011, 13:54
von BlackJack
@Robokopp: Wenn der Aufruf der `settings()`-Methode klappt, bekommst Du gleich das nächste Problem: Sie definiert ein `settings`-Attribut und damit ist dann die Methode nicht mehr unter diesem Namen erreichbar. An ein Attribut kann eben immer nur ein Objekt gebunden sein.
Re: Neues Fenster erzeugen
Verfasst: Sonntag 13. Februar 2011, 13:56
von Robokopp
Okay sry
hier mal der ganze code
Code: Alles auswählen
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
exit = QtGui.QAction('Quit', self)
settings=QtGui.QMenu("Settings", self)
self.resize(800, 400)
self.setWindowTitle(str('Settings'))
menubar = self.menuBar()
file = menubar.addMenu('&Options')
file.addAction(settings)
file.addAction("Help")
file.addAction("About")
file.addAction(exit)
settings.triggered.connect(self.settings)
exit.triggered.connect(self.close)
def settings(self):
self.settings = QtGui.QWidget(self)
self.settings.show()
app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
Wie mit einem Slot verbinden?
Muss ich doch bei exit auch nicht machen und es klappt
@BlackJack
Müsste ich dann die Methode umbenennen?
Re: Neues Fenster erzeugen
Verfasst: Sonntag 13. Februar 2011, 14:05
von Hyperion
Das ganze ist ja nicht mal ausführbar! Den Fehler hättest Du doch längst posten können!
Robokopp hat geschrieben:
Code: Alles auswählen
# So ist es richtig
exit = QtGui.QAction('Quit', self)
# Das ist KEINE QAction!
settings=QtGui.QMenu("Settings", self)
# wozu das hier?
menubar = self.menuBar()
# file ist kein guter Name, in diesem Zusammenhang eh nicht
file = menubar.addMenu('&Options')
# wäre settings eine QAction, wäre das richtig!
file.addAction(settings)
file.addAction(exit)
# prinzipiell richtig, wenn settings eine QAction wäre
settings.triggered.connect(self.settings)
# Genau HIER verbindest Du die Aktion doch mit einem SLOT!!!
exit.triggered.connect(self.close)
def settings(self):
# Hier solltest Du imho einen Dialog nutzen.
self.settings = QtGui.QWidget(self)
self.settings.show()
app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
Wie mit einem Slot verbinden?
Muss ich doch bei exit auch nicht machen und es klappt
Doch! Siehe Kommentare im Code
Re: Neues Fenster erzeugen
Verfasst: Sonntag 13. Februar 2011, 14:08
von Hyperion
Vielleicht noch ein kleiner Tipp: Mit dem QtDesigner kannst Du die Menüs bereits komfortabel anlegen und die Actions definieren. Lediglich das connecten auf eigene Slots musst Du dann später manuell vornehmen. Standard-Slots wie "close" kannst Du sogar auch schon im Designer mit einer Action verbinden.
Re: Neues Fenster erzeugen
Verfasst: Sonntag 13. Februar 2011, 14:16
von Robokopp
ja schon, aaber
wenn ich nun settings = QtGui.QAction("settings", self) verwende, geht es genauso wenig.
Hatte das vorher so, aber dann dachte ich es liegt wohl an QAction, weil ich immer einen Fehler mit "QAction" bekommen habe, weswegen ich das geändert habe
das menubar = self.menuBar() habe ich aus irgendeinem Example entnommen, genauso wie die Bezeichnung "File"
LOL: Es geht auf einmal, aber ich weiß jetzt nicht warum. Hab das eigentlich genauso wie vorher...
Naja mit dem Designer kann ich zur Zeit noch garnix anfangen.Da fehlen mir irgendwie noch die Zusammenhänge
Ich will mir erstmal die Basics aneignen, um zu sehen, wie das alles funktioniert
Edit:Nächstes Problem
Ich habe ein paar Buttons im erzeugten QDialog erstellt.Die werden nicht angezeigt und Windowresize klappt auch nicht
Re: Neues Fenster erzeugen
Verfasst: Sonntag 13. Februar 2011, 14:31
von Hyperion
Robokopp hat geschrieben:
wenn ich nun settings = QtGui.QAction("settings", self) verwende, geht es genauso wenig.
Hatte das vorher so, aber dann dachte ich es liegt wohl an QAction, weil ich immer einen Fehler mit "QAction" bekommen habe, weswegen ich das geändert habe.
Man kann ja trotz korrekter Klassen durchaus noch Fehler machen, aber "planloses" Ändern nach "Trial & Error" ist beim Programmieren selten zielführend. Du solltest Dir dann besser mal die Dokumentation angucken, oder Code-Schnipsel, die so etwas zeigen. Bei dem hättest Du Dir auch mal ein Beispiel im Desigber bauen können, das ui-File manuell per pyuic in eine Python-Datei wandeln und Dir angucken, wie die Jungs von Pyqt das "lösen".
das menubar = self.menuBar() habe ich aus irgendeinem Example ...
Vielleicht hatte es da auch Sinn! Hier ist es doch sinnlos, da Du doch nur eine Objektvariable an einen lokalen Namen bindest.
Code: Alles auswählen
menubar = self.menuBar()
file_menu = menubar.addMenu('&Options')
# ist doch so einfacher
file_menu = self.menuBar().addMenu('&Options')
... entnommen, genauso wie die Bezeichnung "File"
Dann war dieses Beispiel nicht gut

(Kann ja auch ein C++ Beispiel gewesen sein?). Achte einfach darauf, dass man built-ins am besten nicht überschreibt. Viele Editoren mit Syntax-Highlighting bieten ja sogar spezielle Hervroherbungen für built-ins. Gibt auch Tools, die so etwas prüfen:
http://pychecker.sourceforge.net/ (Man hat ja tatsächlich nicht immer alles im Kopf)
Naja mit dem Designer kann ich zur Zeit noch garnix anfangen.Da fehlen mir irgendwie noch die Zusammenhänge
Ich will mir erstmal die Basics aneignen, um zu sehen, wie das alles funktioniert
Prinzipiell auch eine gute Idee! Aber wie ich es oben beschrieb, kann einem der Designer da durchaus ja auch Hilfen geben, wie oben beschrieben beispielsweise.
Ich kann Dir auf jeden Fall auch mal die Snippet-Seite von lunar empfehlen; da findet man viel nützliches
https://bitbucket.org/lunar/snippets/src