Dialog-Fenster öffnen.

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Madmartigan hat geschrieben: Du kannst dem gern widersprechen, das ändert aber nichts an der Aussage. Und Aussagen haben keinen Wahrheitsgehalt, daher ist die Behauptung sie wäre schlicht falsch, schlicht nicht zu beweisen.
Hu? Natürlich haben Aussagen einen Wahrheitsgehalt - das Wort Aussagenlogik beinhaltet das sogar!
Madmartigan hat geschrieben: Ich unterstelle mal du hast mich missverstanden. Ich sprach davon, dass wenn ein GUI zwingend erforderlich ist, sei der Code "schlecht". Nicht wenn es der Einsatzzweck erfordert!
Hä? Wenn eine GUI erforderlich ist, ist der Code also schlecht. Wenn es der Einsatzzweck erfordert, ist es natürlich ok‽ Sorry, das kapiert ja kein Mensch mehr, denn da widersprichst Du Dir ja selber und mit letzterem Teil stimmst Du mir ja zu!
Madmartigan hat geschrieben: Selbstverständlich liefert man z.B. Photoshop nicht ohne GUI aus, das macht keinen Sinn. Auch ein Spiel braucht ein GUI, soweit sind wir uns einig.
Na also, genau das sagte ich doch! Natürlich gibt es Tools, die zur Laufzeit *zwingend* eine GUI voraussetzen; das bedeutet ja nicht, dass diese nicht sehr gut testbar geschrieben sind!
Madmartigan hat geschrieben: Was macht aber der GameServer? Braucht der ein GUI? Nein! Also muss der ganze Code prinzipiell ohne GUI funktionieren und automatisiert testbar(!) sein.
Äh... nö. Ein Server hat idR auch externe Abhängigkeiten, die eben *nicht* per Unit Test testbar sind, z.B. sämtliche Netzwerkkommunikation. Auch bei dieser muss man irgend wie faken - genau wie bei einer GUI-Komponente ;-) Nur sehe ich den Widerspruch zu mir nicht... natürlich gibt es jede Menge an Programmen, der keine GUI hat und auch keine zur Laufzeit benötigt. Darum ging es doch gar nicht!

Ich denke Du hast da zu vorschnell eine These raus gehauen, die so einfach nicht stimmt.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Oh wow, du mühst dich hier wirklich ab und kommentierst alte Beiträge. Da muss dir ja etwas gewaltig auf den Magen geschlagen haben, dass meine Sätze deine Aufmerksamkeit derart in Anspruch nehmen.
Hyperion hat geschrieben:Hä? Wenn eine GUI erforderlich ist, ist der Code also schlecht. Wenn es der Einsatzzweck erfordert, ist es natürlich ok‽ Sorry, das kapiert ja kein Mensch mehr, denn da widersprichst Du Dir ja selber und mit letzterem Teil stimmst Du mir ja zu!
Du hast die Begründung nicht verstanden. Es ging darum, ob ein GUI notwendig sei, damit ein zugrunde liegender Code funktionieren darf. Meine Antwort ist doch diesbezüglich eindeutig. Der Code muss ohne GUI lauffähig sein, hier fragt man nicht nach sinnvoller Einsetzbarkeit im Sinne des menschlichen Nutzers. Selbstverständlich benötigt Letzterer oft eine passende Schnittstelle zur Verwendung des Codes, daher ja Interface. Wenn das nicht klar ist, dann empfehle ich eindringliche Literatur, Jef Raskin wäre ein Anfang.
Hyperion hat geschrieben:Natürlich gibt es Tools, die zur Laufzeit *zwingend* eine GUI voraussetzen; das bedeutet ja nicht, dass diese nicht sehr gut testbar geschrieben sind!
Voraussetzen - nur weil der Mensch das Tool verwendet. Ich bin im sechsten Jahr Tool- und Engine-Entwickler - rein zum Funktionieren braucht meiner Erfahrung nach kein einziges Tool ein GUI. Tests auf Fehler und Funktionalität funktionieren ohne GUI, mit GUI sind die Tests nicht automatisierbar und benötigen menschliche Interaktion (Usability-Tests).

Automatisiert zu testen beschränkt sich nicht auf Unittests. Wenn das deine Annahme war, spare ich mir mal den Kommentar zu dem Satz. Fakes gehören ja wohl auch eher in den Bereich Sales, Producing und Marketing....
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Madmartigan hat geschrieben:Oh wow, du mühst dich hier wirklich ab und kommentierst alte Beiträge. Da muss dir ja etwas gewaltig auf den Magen geschlagen haben, dass meine Sätze deine Aufmerksamkeit derart in Anspruch nehmen.
Ja, insbesondere wenn der Kommentar einen überheblichen Tonfall hat und dazu noch inhaltlich falsch ist ;-)

(Ich erinnere mich gerne an so einen Typen aus dem "Perfekten Dinner": "Ich habe schon besseres Terrakotta gegessen ..." :mrgreen: )
Madmartigan hat geschrieben: Du hast die Begründung nicht verstanden. Es ging darum, ob ein GUI notwendig sei, damit ein zugrunde liegender Code funktionieren darf. Meine Antwort ist doch diesbezüglich eindeutig. Der Code muss ohne GUI lauffähig sein, hier fragt man nicht nach sinnvoller Einsetzbarkeit im Sinne des menschlichen Nutzers.
Nein! Du schriebst:
Madmartigan hat geschrieben: Jede Anwendung, die ein GUI zur Laufzeit zwingend erfordert, ist "schlecht" geschrieben.
Da steht etwas von Anwendung - das ist doch eine ganz andere Ebene! Natürlich besitzt eine Anwendung idR. eine Menge GUI unabhängigen Code; doch die Aussage bezieht sich eindeutig auf die Ausführung eines Programms - und das macht sie zu einer falschen.
(Ich hoffe Du hast mittlerweile eingesehen, dass Aussagen sehr wohl Logik beinhalten (können) und daher sehr wohl richtig oder falsch sein können?)
Madmartigan hat geschrieben: Voraussetzen - nur weil der Mensch das Tool verwendet. Ich bin im sechsten Jahr Tool- und Engine-Entwickler - rein zum Funktionieren braucht meiner Erfahrung nach kein einziges Tool ein GUI. Tests auf Fehler und Funktionalität funktionieren ohne GUI, mit GUI sind die Tests nicht automatisierbar und benötigen menschliche Interaktion (Usability-Tests).
Natürlich kann man auch automatisierte Tests auf dem fertigen und kompletten Programm durchführen! Dafür gibt es gute Werkzeuge a la Selenium für Webanwendungen oder Ranorex als Rundum-sorglos-Paket. Solche Integrationstests sind sogar sehr sinnvoll und sollten ja gerade auf dem wirklich lauffähigen Programm stattfinden.

Und natürlich kann ich als Entwickler für *mein* Programm eine GUI zur Laufzeit zwingend voraussetzen; vielleicht will ich einfach keine Batch-Verarbeitung für meinen Editor schreiben. Damit kannst Du doch gar keine Aussage zum Design und der Code-Qualität an sich treffen!
Madmartigan hat geschrieben: Fakes gehören ja wohl auch eher in den Bereich Sales, Producing und Marketing....
Die Nomenklatur in dem Bereich geht leider viel durcheinander. Ich fand die Definition von Roy Osherove immer am besten: Fake allgemein für ein Test-Double; Stub für reines Immitieren, Mock für das Auswerten eines Tests. Ich denke darüber muss man nicht wirklich streiten... nenn es doch, wie du willst ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Ich habe es endlich geschafft. Nun, ich möchte mich bei euch so herzlich danken, dass ihr mir geholfen habt. Verspürt ihr Sarkasmus? Dann seid ihr auf dem richtigen Weg. Mein Code sieht wie folgt aus:

Code: Alles auswählen

import sys 
from PyQt4 import QtGui, QtCore 
from Hauptfenster import Ui_Hauptdialog as Dlg
from Dialog import Ui_Dialog2 as Dlg1
     
#Der Hauptdialog, wobei ich eher ein Hauptfenster draus machen wuerde
class MeinDialog(QtGui.QDialog, Dlg): 
    def __init__(self): 
        QtGui.QDialog.__init__(self) 
        self.setupUi(self)
                    
        # Slots einrichten 
        self.connect(self.buttonOK, 
                QtCore.SIGNAL("clicked()"), self.onOK) 
        self.connect(self.buttonAbbrechen, 
                QtCore.SIGNAL("clicked()"), self.onAbbrechen)
        self.connect(self.Neu,
                QtCore.SIGNAL("clicked()"), self.onNeu)
            
    def onOK(self): 
            # Daten auslesen 
            d = {} 
            print "Vorname: %s" % self.vorname.text() 
            print "Nachname: %s" % self.nachname.text() 
            print "Adresse: %s" % self.adresse.toPlainText() 
            datum = self.geburtsdatum.date().toString("dd.MM.yyyy") 
            print "Geburtsdatum: %s" % datum
    
            if self.agb.checkState(): 
                print "AGBs akzeptiert." 
            if self.newsletter.checkState(): 
                print "Katalog bestellt" 
            self.close()
    
    def onAbbrechen(self): 
            print "Schade" 
            self.close()
        
    def onNeu(self):
            dialog2 = MeinNeuDialog()
            dialog2.exec_()
    
#Der leere Dialog
class MeinNeuDialog(QtGui.QDialog, Dlg1): 
    def __init__(self): 
        QtGui.QDialog.__init__(self) 
        self.setupUi(self)
    
# Diese Routine ist quasi der Einstiegspunkt fuer das Programm
# if __name__ == '__main__':
# Hier wird eine Instanz der Applikation erstellt
app = QtGui.QApplication(sys.argv)
# Hier wird eine Instanz der Klasse für das Hauptfenster erstellt
winHauptfenster = MeinDialog()
# Mit der Methode showMaximized wird das Hauptfenster maximiert angezeigt
winHauptfenster.exec_()
# Wenn die Instanz winHauptfenster geschlossen wird, dann wird auch die 
# Applikation beendet
# sys.exit(app.exec_())
Nun eine Frage: Ich musste Zeile 50 und 59 "auskommentieren", da das Programm sonst nicht richtig beendet wurde. Dies sah ich am Kommandofenster. Liegt es daran, weil es sich hierbei um Dialoge handelt?
EmaNymton
User
Beiträge: 174
Registriert: Sonntag 30. Mai 2010, 14:07

Deine Dialoge werden zwar angezeigt, du dürftest damit aber wenig anfangen können, da du die Hauptschleife, die für das Eventhandling zuständig ist gar nicht ausführst (auskommentierte Zeile 59):
http://pyqt.sourceforge.net/Docs/PyQt4/ ... .html#exec

Dann noch ein paar grundlegende Dinge, die auffallen:

Du kannst du ui-Dateien direkt ohne den Umweg über pyuic einbinden, was imho wesentlich einfacher ist. Dazu gibt es das uic-Modul bei PyQt:
http://pyqt.sourceforge.net/Docs/PyQt4/ ... uic-module

Du schreibst die Connections noch im alten Format, das neuere ist wesentlich lesbarer:
http://pyqt.sourceforge.net/Docs/PyQt4/ ... ng-signals

Zeile 50 auszukommentieren hat erst mal überhaupt keinen Einfluss darauf, ob das Programm läuft oder nicht:
http://abop-german.berlios.de/read/module-name.html

Ich weiß nicht, was bzw. ob du etwas mit den Dialogen bezwecken willst, aber normalerweise beendet man einen Dialog mit accept, reject oder done, nachzulesen in der Dokumentation:
http://pyqt.sourceforge.net/Docs/PyQt4/ ... ml#details

Du solltest dir angewöhnen (Zeile 39-41), Objekte mit self an eine Instanz zu binden oder beim Erzeugen des Dialogs ein parent anzugeben, da im Zweifelsfall das erzeugte Objekt ohne jegliche Referenz einfach gelöscht wird, was zu unschönen Effekten führen kann.

P.S.: Du solltest übrigens nicht mehr das Openbook von Galileo verwenden (daher kommt doch das Beispiel, oder?), das ist eher schlecht, such einfach mal nach Kritik ;)
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo EmaNymton,

vielen Danke für deine ausführliche Antwort. Ja von daher kommt das Beispiel. Irgendwie muss man doch anfangen, während andere mich gerne darauf hin verweisen, dass ich doch erstmal Bücher verschlucken soll. Für mich ist das Erfolgserlebnis beim Programmieren wichtig, daher versuche ich nebenbei zu lernen, in dem ich mich gleich an die Materie heranwage. Im Grunde will ich mit den Dialogen nichts bezwecken. Ich bin noch sehr sehr sehr sehr frisch dabei, und mir ging es einfach darum, dass, wenn ich eine Form / ein Dialog im Qt-Designer angefertigt habe, ich dann mittels Buttons weitere Dialoge öffnen kann - nicht mehr und nicht weniger. Du siehst, mein Anliegen ist ganz elementar. Andere tun so, als will ich gleich groß einsteigen und eine "Alles-vernichtende-Software" programmieren :-)

Ich mag gerne Kritik, aber man sollte mir auch Lösungsvorschläge aufzeigen, anstatt, wie die anderen, mir immer fein auf Lektüren zu verweisen. Das ist absolut keine Hilfe. Entschuldige, ich kann es nicht lassen, die Hilfe-Kompetenz der anderen gänzlich in Frage zu stellen.

Gruß
Sophus
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

EmaNymton hat geschrieben:Deine Dialoge werden zwar angezeigt, du dürftest damit aber wenig anfangen können, da du die Hauptschleife, die für das Eventhandling zuständig ist gar nicht ausführst (auskommentierte Zeile 59):
http://pyqt.sourceforge.net/Docs/PyQt4/ ... .html#exec
Diesbezüglich habe ich ja schon angesprochen, dass ich die auskommentieren musste, da das Programm nicht richtig beendet wird. Daraufhin kam ja die Frage meinerseits, woran es liegen könnte? Lasse ich diese besagte Zeile auskommentiert, dann wird beim Beenden "Schade" in die Dos-Eingabeforderung geschrieben. Wenn ich aber diese Zeile nicht auskommentiere, dann beendet das Programm zwar, aber in der Eingabeforderung steht dann nicht "Schade".
EmaNymton hat geschrieben: Du solltest dir angewöhnen (Zeile 39-41), Objekte mit self an eine Instanz zu binden oder beim Erzeugen des Dialogs ein parent anzugeben, da im Zweifelsfall das erzeugte Objekt ohne jegliche Referenz einfach gelöscht wird, was zu unschönen Effekten führen kann.
Kannst du mir dafür ein Beispiel aufzeigen, damit ich auch verstehe, was du mir erzählen willst?

Gruß
Sophus
BlackJack

@Sophus: Du sollst keine Bücher verschlucken oder graue Theorie lernen, sondern die Grundlagen. Anhand von Tutorials die in aller Regel voll von praktischen Beispielen sind, die man ausprobieren, verändern, und nachvollziehen muss. Das ist alles andere als graue Theorie. Was Du hier so beschönigend „Lösungsvorschläge” und „Beispiele” nennst, sind doch in Wirklichkeit Komplettlösungen für Dein jeweiliges ganz konkretes Problem, also Code den Du nicht selber schreiben kannst, weil Dir Wissen fehlt, und den Du Dir deshalb hier von anderen erbetteln willst. In der Hoffnung das Du Dir den Code dann anschaust und wie durch Zauberhand die ganzen Zusammenhänge erkennst, die man sich eigentlich er*arbeiten* muss. Genau darum willst Du Dich offensichtlich drücken — da *selbst* ein wenig Zeit für aufzuwenden.

Deine Taktik würde dazu führen das Du Programme aus Code-Schnippseln zusammen baust, die Du nicht verstanden hast. Und damit dann Programme schreibst die Du nicht verstehst, wo Du nicht verstehst warum die funktionieren, und damit noch nicht einmal sicher *ob* sie das auch tun, oder ob es nur durch Zufall noch nicht in sich zusammen gefallen ist. *Das* ist kein Programmieren. Du willst rennen bevor Du laufen gelernt hast.

Ich habe das Gefühl dass Du die Komplexität von GUI-Programmierung in Python schlicht unterschätzt weil das in VB6 so einfach war. Das Du hier nur mit Dialogen experimentieren willst hat glaube ich jeder verstanden, was Dir nicht in den Kopf gehen will, ist, dass man dafür objektorientierte Programmierung verstanden haben muss. Das ist eine notwendige Voraussetzung bei Python und Qt. Je länger Du Dich gegen diese Erkenntnis wehrst, desto mehr Zeit verplemperst Du mit dieser unnötigen Diskussion den Leuten die Ahnung von der Materie haben, vorzuwerfen sie hätten doch keine Ahnung. Ich habe früher auch mal in VB6 programmiert und ich kenne Python und Qt, und das ist *deutlich* unterschiedlich. Die Zeit in der Du hier versuchst diese Tatsache zu ignorieren, hättest Du besser in das lernen von Python, OOP, und Qt investieren können.
EmaNymton
User
Beiträge: 174
Registriert: Sonntag 30. Mai 2010, 14:07

Sophus hat geschrieben:[...] Für mich ist das Erfolgserlebnis beim Programmieren wichtig, daher versuche ich nebenbei zu lernen, in dem ich mich gleich an die Materie heranwage.[...] Du siehst, mein Anliegen ist ganz elementar. Andere tun so, als will ich gleich groß einsteigen und eine "Alles-vernichtende-Software" programmieren :-)

Ich mag gerne Kritik, aber man sollte mir auch Lösungsvorschläge aufzeigen, anstatt, wie die anderen, mir immer fein auf Lektüren zu verweisen. Das ist absolut keine Hilfe. Entschuldige, ich kann es nicht lassen, die Hilfe-Kompetenz der anderen gänzlich in Frage zu stellen.
Ich denke dir wurden Lösungsvorschläge aufgezeigt und zwar dich erstmal mit den grundlegenden Dingen soweit vertraut zu werden, dass es daran nicht schon scheitert, denn das macht auf Dauer keinen Spaß und ist imho eher demotivierend. Hier will dich auch keiner als dumm oder faul darstellen, aber wie BlackJack bereits geschrieben hat ist GUI-Programmierung mit Qt eben nicht vergleichbar mit VB oder Delphi, da du OOP vorher verstanden haben solltest. Gerade deine Nachfrage zeigt, dass du es noch nicht verstanden hast. Hier wäre es jetzt zum Beispiel eine gute Möglichkeit mal nach den Begriffen zu suchen, die ich genannt habe, also was ist eine Instanz, was bedeutet das parent bei Qt usw. Das Netz ist voll von Informationen.

Du könntest zwar jetzt erwarten, dass ich dir detailiert erkläre, wie das funktioniert, aber das haben schon etliche Leute in Netz in Tutorials erklärt, die sich da auch z.T. didaktische Überlegungen zu gemacht haben. Da hier alle freiwillig ihre Zeit opfern, empfiehlt man dann so ein Tutorial erstmal selbst durchzuarbeiten. Wenn du dann dabei ein Verständnisproblem hast, hat keiner ein Problem dir zu antworten, wenn du einen Thread eröffnest a la "Ich bin bei diesem Tutorial so weit gekommen und habe jetzt an der Stelle ein konkretes Problem...". Das Forum würde aber auf Dauer so nicht funktionieren, wenn jeder sich Programmtexte zusammensucht und hier nach einem Fehler fragt.

Ich kenne dein Vorgehen nur zu gut, da eine Vielzahl meiner Schüler es genauso machen und glaube mir, es führt eher zu Frustrationen als zu einem Erfolg! ;)

Edit: Und zu deinem Problem bzgl. der Auskommentierung und zukünftiger Fehlersuche. Baue dir doch mal print statements ein, die jeweils angeben, was gerade aufgerufen wird, also z.B.:

Code: Alles auswählen

# Diese Routine ist quasi der Einstiegspunkt fuer das Programm
if __name__ == '__main__':
# Hier wird eine Instanz der Applikation erstellt
    app = QtGui.QApplication(sys.argv)
# Hier wird eine Instanz der Klasse für das Hauptfenster erstellt
    winHauptfenster = MeinDialog()
# Mit der Methode showMaximized wird das Hauptfenster maximiert angezeigt
    print "vor hauptfenster"
    winHauptfenster.exec_()
    print "nach hauptfenster"
# Wenn die Instanz winHauptfenster geschlossen wird, dann wird auch die
# Applikation beendet
    sys.exit(app.exec_())
Dann wirst du erkennen, dass beim Programmstart nur "vor hauptfenster" ausgegeben wird, das Programm erstmal also gar nicht weiter kommt. Nach dem Beenden wird die Ausgabe von Dialog und "nach hauptfenster" ausgegeben und das Programm wird nicht beendet. Das liegt eben daran, dass er jetzt den letzten Befehl ausführt und vergeblich auf einen Rückgabewert von app.exec_() wartet, der aber nie kommen wird ;)
So, wie du exec_ für den Dialog hier einsetzt funktioniert das nicht, du möchtest lieber show() verwenden, das nicht dein Programm blockiert, siehe auch in der Doku:
http://pyqt.sourceforge.net/Docs/PyQt4/ ... ml#details
Benutzeravatar
Madmartigan
User
Beiträge: 200
Registriert: Donnerstag 18. Juli 2013, 07:59
Wohnort: Berlin

Hyperion hat geschrieben:
Madmartigan hat geschrieben:Oh wow, du mühst dich hier wirklich ab und kommentierst alte Beiträge. Da muss dir ja etwas gewaltig auf den Magen geschlagen haben, dass meine Sätze deine Aufmerksamkeit derart in Anspruch nehmen.
Ja, insbesondere wenn der Kommentar einen überheblichen Tonfall hat und dazu noch inhaltlich falsch ist ;-)
[...]
Nach dem Sermon hatte ich ernsthaft für einen kurzen Moment über eine adäquate Antwort nachgedacht, diese süffisante Idee dann aber ob des Fehlens jeglichen Sinnes verworfen. Ehrlich, ich sehe mich durch nichts, was du versuchst, zu sagen, auch nur im Ansatz widerlegt. Anderen inhaltliche Fehler andichten wollen und der eigene Geltungsdrang sickert unbeholfen durch die Zeilen ... nuja

Das "Perfekte Dinner" für einen Vergleich zu gebrauchen, trennt uns nicht nur inhaltlich bereits an der Basis.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Madmartigan hat geschrieben: Nach dem Sermon hatte ich ernsthaft für einen kurzen Moment über eine adäquate Antwort nachgedacht, diese süffisante Idee dann aber ob des Fehlens jeglichen Sinnes verworfen. Ehrlich, ich sehe mich durch nichts, was du versuchst, zu sagen, auch nur im Ansatz widerlegt. Anderen inhaltliche Fehler andichten wollen und der eigene Geltungsdrang sickert unbeholfen durch die Zeilen ... nuja
So kann man sich natürlich auch das der Affäre ziehen - ein Schelm, wer böses dabei denkt :evil:
Entweder Du siehst Deine Widersprüche wirklich nicht, oder aber Du bist zu stolz einen Fehler zuzugeben - in beiden Fällen ist das schade.
Madmartigan hat geschrieben: Das "Perfekte Dinner" für einen Vergleich zu gebrauchen, trennt uns nicht nur inhaltlich bereits an der Basis.
Wenn ein Ausspruch gut passt, nutze ich ihn. Der Gehalt ist ein Glück unabhängig vom Medium ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Nun habe ich folgendes Problem. Ich will mit Hilfe der Datei Start.py eine andere Datei aufrufen, da ich auslagern möchte. Der Start des Programms funktioniert solange gut, bist in der Datei MDIForm.py die Zeilen 132-135 so stehen wie jetzt, oder wenn eben diese eben genannten Zeilen auskommentiert werden. ABER kommentiere ich die Zeilen 133-135 aus, und versuche dann das Programm über Start.py auszuführen, dann sehe ich kein Fenster. Und es erscheint in der Python Shell auch keinerlei Fehlermeldungen. Man könnte ja sagen "lass die Zeilen stehen. Aber ich hätte das ohne die Print-Zeilen.

Jemand eine Idee?

P.S. So nebenbei, ich weiß, dass ich die Kommentare hier missbrauche, aber sie sollen einfach dazu dienen, dass ich bestimmte Abschnitte besser kennenlerne. Ich möchte also nichts davon hören, dass man "anders" kommentiert :-)

Start.py

Code: Alles auswählen

# -*- coding: utf-8 -*-
# Die Datei MDIForm.py befindet sich im Unterverzeichnis namens Xarphus
# und wird von dort importiert.
# Und in dieser Datei wird die Klasse "MDIFormular" ausgerufen.
from Xarphus.MDIForm import MDIFormular
MDIForm.py

Code: Alles auswählen

# -*- coding: cp1252 -*-
# -*- coding: utf-8 -*-
import sys  # Wie alle Module muss auch das Modul sys mittels der import-Anweisung eingebunden werden,
            # also import sys. Das sys-Modul stellt Informationen in Konstanten, Funktionen und
            # Methoden über den Python-Interpreter zur Verfügung.

from PyQt4.QtGui import QMainWindow, QApplication, QAction
from PyQt4.QtCore import SIGNAL, SLOT

class MDIFormular(QMainWindow):
    def __init__ (self, parent=None):
        QMainWindow.__init__(self, parent)

        # Die MainWindow-Form bekommt hier einen Titel.
        self.setWindowTitle(' Xarphus Build 0.1')

        # Hier wird ein bestimmter Text über die Statusbar ausgegeben.
        self.statusBar().showMessage('Ready')

        ##########################################################################
        ###### Menupunkte gehören zum Menu "Verwaltung" ##########################
        ##########################################################################
        # Menupunkt bekommt eine Beschriftung, hier 'Film'
        mnuFilm = QAction ('Filme', self)
        # Hier wird zu der Beschrifung hinzugefügt, über welche Tastenkombinationen
        # man zum Film kommt.
        mnuFilm.setShortcut('Ctrl+F')
        # Sobald man mit der Maus über das Untermenu fährt, erscheint in der Statusbar
        # der Text, hier 'Filme hinzufügen'.
        mnuFilm.setStatusTip('Filme hinzufügen')

        mnuBuch = QAction ('Bücher', self)
        # Hier wird zu der Beschrifung hinzugefügt, über welche Tastenkombinationen
        # man zum Film kommt.
        mnuBuch.setShortcut('Ctrl+F')
        # Sobald man mit der Maus über das Untermenu fährt, erscheint in der Statusbar
        # der Text, hier 'Filme hinzufügen'.
        mnuBuch.setStatusTip('Bücher hinzufügen')

        mnuMusik = QAction ('Musik', self)
        # Hier wird zu der Beschrifung hinzugefügt, über welche Tastenkombinationen
        # man zum Film kommt.
        mnuMusik.setShortcut('Ctrl+F')
        # Sobald man mit der Maus über das Untermenu fährt, erscheint in der Statusbar
        # der Text, hier 'Filme hinzufügen'.
        mnuMusik.setStatusTip('Musik hinzufügen')

        mnuAdressbuch = QAction ('Kontakte', self)
        # Hier wird zu der Beschrifung hinzugefügt, über welche Tastenkombinationen
        # man zum Film kommt.
        mnuAdressbuch.setShortcut('Ctrl+F')
        # Sobald man mit der Maus über das Untermenu fährt, erscheint in der Statusbar
        # der Text, hier 'Filme hinzufügen'.
        mnuAdressbuch.setStatusTip('Kontaktdaten hinzufügen')

        mnuNotizen = QAction ('Notizen', self)
        # Hier wird zu der Beschrifung hinzugefügt, über welche Tastenkombinationen
        # man zum Film kommt.
        mnuNotizen.setShortcut('Ctrl+F')
        # Sobald man mit der Maus über das Untermenu fährt, erscheint in der Statusbar
        # der Text, hier 'Filme hinzufügen'.
        mnuNotizen.setStatusTip('Notizen hinzufügen')

        mnuNotizen = QAction ('Notizen', self)
        # Hier wird zu der Beschrifung hinzugefügt, über welche Tastenkombinationen
        # man zum Film kommt.
        mnuNotizen.setShortcut('Ctrl+F')
        # Sobald man mit der Maus über das Untermenu fährt, erscheint in der Statusbar
        # der Text, hier 'Filme hinzufügen'.
        mnuNotizen.setStatusTip('Notizen hinzufügen')

        mnuTrennstrich = QAction ('-', self)

        # Menupunkt bekommt eine Beschriftung, hier 'Beenden'
        mnuMainWindowClose = QAction ('Beenden', self)
        # Hier wird zu der Beschrifung hinzugefügt, über welche Tastenkombinationen
        # man dwn MainWindow beenden kann.
        mnuMainWindowClose.setShortcut('Ctrl+Q')
        # Sobald man mit der Maus über das Untermenu fährt, erscheint in der Statusbar
        # der Text, hier 'Programm beenden'.
        mnuMainWindowClose.setStatusTip('Programm beenden')
        # Klickt man auf auf das Untermenu "MainWindowClose" wird ein bestimmtes Ereignis
        # ausgelöst, hier wird der MainWindow geschlossen.
        self.connect(mnuMainWindowClose, SIGNAL('triggered()'), SLOT('close()'))
        #self.mnuMainWindowClose.triggered.connect(close)
        
        ##########################################################################
        ###### Menupunkte gehören zum Menu "Info" ################################
        ##########################################################################
        # Menupukt bekommt eine Beschriftung, hier 'Film'
        mnuUeber = QAction ('Über Xarphus', self)
        # Hier wird zu der Beschrifung hinzugefügt, über welche Tastenkombinationen
        # man zum Film kommt.
        mnuUeber.setShortcut('Ctrl+F')
        # Sobald man mit der Maus über das Untermenu fährt, erscheint in der Statusbar
        # der Text, hier 'Filme hinzufügen'.
        mnuUeber.setStatusTip('Alles über Xarphus')
        # Statusbar wird erstellt.
        self.statusBar()

        ##########################################################################
        ###### Menuleiste "Verwaltung" ###########################################
        ##########################################################################
        # Eine eigenständige Menubar wird erstellt. In diesem Fall nur einer, und zwar mit der
        # Beschriftung "Verwaltung"
        menubar = self.menuBar()
        MNUL_Verwaltung = menubar.addMenu('&Verwaltung')
        # Zum Menü "Verwaltung" werden weitere Menüpunkte erstellt.
        # MNUL steht hier für MenuLeiste
        # MNUP steht hier für MenuPunkt
        MNUL_Verwaltung.addAction(mnuFilm)
        MNUL_Verwaltung.addAction(mnuBuch)
        MNUL_Verwaltung.addAction(mnuMusik)
        MNUL_Verwaltung.addAction(mnuAdressbuch)
        MNUL_Verwaltung.addAction(mnuNotizen)
        MNUL_Verwaltung.addAction(mnuTrennstrich)
        MNUL_Verwaltung.addAction(mnuMainWindowClose)

        ##########################################################################
        ###### Menuleiste "Info" #################################################
        ##########################################################################
        # Eine eigenständige Menubar wird erstellt. In diesem Fall nur einer, und zwar mit der
        # Beschriftung "Info"
        # MNUL steht hier für MenuLeiste
        # MNUP steht hier für MenuPunkt
        menubar = self.menuBar()
        MNUL_Info = menubar.addMenu('&?')
        # Zum Menü "Verwaltung" werden weitere Menüpunkte erstellt.
        MNUL_Info.addAction(mnuUeber)

# Main Routine
if __name__ == "__main__":
	print 'Dieses Programm läuft als Main.'
else:
	print 'Das Programm wird von einem anderen Modul importiert.'
app = QApplication(sys.argv)
MDIWindow = MDIFormular()
MDIWindow.showMaximized()
sys.exit(app.exec_())
EmaNymton
User
Beiträge: 174
Registriert: Sonntag 30. Mai 2010, 14:07

Wenn deine Module in einem Unterverzeichnis liegen, brauchst du in diesem Unterverzeichnis eine __init__.py, siehe auch:
https://docs.python.org/2/tutorial/modu ... l#packages

Noch ein paar Dinge, die mir spontan auffallen:

Welches coding hat MDIForm denn jetzt? cp1252 oder utf8?

Die ganzen QActions könnte man wesentlich kürzer formulieren, indem man entweder den Qt-Designer verwendet oder das ganze über eine for-Schleife erzeugen lässt, die die Informationen z.B. aus einer Liste nimmt, deren Elemente Tuple sind a la (Bezeichnung, Shortcut, Statustip, Action).

Verwende unicode bei deinen Strings, sonst bekommst du Probleme mit der Anzeige von Umlauten/Sonderzeichen.

Du verwendest immer noch die alte Syntax zum Verbinden von Signalen und Slots.

P.S.: Vielleicht missbrauchst du diesen Thread nicht für Fragen, die mit dem eigentlich Problem nichts mehr zu tun haben und öffnest dafür neue Threads. ;)
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo,

das mit dem Coding werde ich ändern, ich dachte, ich kann beides nehmen - immerhin meckert Python gar nicht. Des Weiteren ist im Unterverzeichnis eine Datei namens __init__.py vorhanden, daran habe ich schon gedacht. Bezüglich der Signals und Slots. Mir ist auch bewusst, dass ich die alten Verwende. Schaue mal genauer hin, und du wirst sehen, dass in Zeile 85 bereits der neue Style benutzt wurde. Warum ich den neuen Style ausgeklammert habe? Klammere ich Zeile 84 aus, und aktiviere Zeile 85, also den neuen Style, bekomme ich folgende Fehlermeldungen im Python Shell:
Traceback (most recent call last):
File "D:\Dan\Python\Xarphus\MDIForm.py", line 137, in <module>
MDIWindow = MDIFormular()
File "D:\Dan\Python\Xarphus\MDIForm.py", line 85, in __init__
self.mnuMainWindowClose.triggered.connect(close)
AttributeError: 'MDIFormular' object has no attribute 'mnuMainWindowClose'
Und zu der For-Schleife bezüglich der QActions. Könntest du mir ein kleines Beispiel geben? Ich bin ein blutiger Anfänger und hätte gern zur Verdeutlichung ein kleines Beispiel, damit ich den Ansatz verstehe.

Gruß
Sophus
BlackJack

@Sophus: Natürlich gibt es so ein Attribut nicht. Genau das passiert wenn man versucht nur durch ”Beispiele” die man nicht verstanden hat, eigene Programme zusammen zu stückeln. An der Stelle muss man halt wissen was `self` in Python's Objektmodell normalerweise bedeutet, also objektorientierte Programmierung in Python verstanden haben.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Entschuldige, wenn ich gleich etwas grantig wirke, aber wie du siehst "hämmer" ich nicht drauf los, sondern kommentiere für mich ausführlich, was genau was an welchen Stellen gemacht wird, damit ich verstehe was da eigentlich passiert, und schreibe nicht (wie du es immer unterschwellig versuchst mir zu zuschieben), dass ich Code aus anderen Beispielen zusammenstückel. Ich möchte vorwärts kommen, und nicht immer ausgebremst werden. Ich wäre also um eine kleine Erklärung dankbar, und hätte was dazu gelernt, anstatt mir immer und immer wieder vorzuhalten, dass es nicht so geht. Ich lerne nun mal anders als du und jeder andere auch.

Danke fürs Lesen, und freue mich über Erklärungen.

Gruß
Sophus
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@Sophus: Vergleiche bitte:

Code: Alles auswählen

class A(object):
    def __init__(self):
        self.x = 1

a = A()
print a.x


class B(object):
    def __init__(self):
        x = 1

b = B()
print b.x
In specifications, Murphy's Law supersedes Ohm's.
BlackJack

@Sophus: Die Erklärungen findest Du in frei im Netz verfügbaren Tutorials und Büchern. Ich werde die sicher jetzt nicht hier für Dich abschreiben und mir die Arbeit machen etwas was dort sehr wahrscheinlich besser erklärt ist, als ich das mal eben so aus dem Ärmel schütteln könnte, noch mal aufschreiben.

Wenn das nicht abgeschrieben war, was hast Du Dir denn dabei gedacht die Zeile mit ``self.`` anzufangen? Wie bist Du ohne Attribuzugriffe verstanden zu haben, auf die Idee gekommen einen zu machen?
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

In der Klasse-A benutzt du die Konvention "self" und in der Klasse-B nicht. Aber anhand dieses einfachen Beispiels ist es unerheblich ob ich die Konvention "self" benutze oder nicht, weil du hier keine Referenz auf ein bestimmtes Objekt brauchst, richtig? Jedoch wird mir anhand deines kleinen Beispiels nicht ersichtlich weshalb es bei beiden Formaten der self unterschiedlich behandelt wird.

Was mich nur etwas verwirrt, ist, dass beim Verwenden des alten Formats der self klappt, und das Programm problemlos ausgeführt wird.

Code: Alles auswählen

87.        self.connect(mnuMainWindowClose, SIGNAL('triggered()'), SLOT('close()'))
Während im New-Sytle das Programm Probleme mit dem self hat.

Code: Alles auswählen

88.        self.mnuMainWindowClose.triggered.connect(close)
Zuletzt geändert von Sophus am Donnerstag 5. Juni 2014, 14:28, insgesamt 1-mal geändert.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

BlackJack hat geschrieben:@Sophus: Die Erklärungen findest Du in frei im Netz verfügbaren Tutorials und Büchern. Ich werde die sicher jetzt nicht hier für Dich abschreiben und mir die Arbeit machen etwas was dort sehr wahrscheinlich besser erklärt ist, als ich das mal eben so aus dem Ärmel schütteln könnte, noch mal aufschreiben.

Wenn das nicht abgeschrieben war, was hast Du Dir denn dabei gedacht die Zeile mit ``self.`` anzufangen? Wie bist Du ohne Attribuzugriffe verstanden zu haben, auf die Idee gekommen einen zu machen?
Ich wäre froh, wenn du mir auch die Zeilennummer sagst, damit ich jetzt nicht die Arbeit machen muss, und erstmal die Zeilen absuchen musst.

Danke.

Sophus
Antworten