Was mache ich falsch ?

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
ciclista
User
Beiträge: 3
Registriert: Samstag 16. Januar 2010, 16:09

Hi
Ich habe da ein Problem bei dem ich einfahc nicht weiterkomme.

Und zwar versuche vom Hauptfenster aus ein Unterfenster zu
öffnen. Zwischen dem Hauptfenster und Unterfenster können
Informationen ausgetauscht werden. Bis dahin klappt das auch
alles völlig problemlos.
Nur wenn ich versuche das Unterfenster wieder zu schließen,
klappt das nicht. Obwohl die Close-Routine definitiv aufgerufen
wird.Ich habe schon alles mögliche ausprobiert, komme
aber einfach nicht weiter.

Hier der Source für das Hauptprogramm (heisst bei mir
ganz einfach: project1.pyw)

Code: Alles auswählen

import sys
from PyQt4 import QtCore, QtGui
from modul1 import Unterfenster

class Hauptfenster(object):
    def __init__(self,parent = None):
        Form1.resize(256, 128)
        Form1.setWindowTitle("Dialogtest")
        self.lineEdit = QtGui.QLineEdit(Form1)
        self.lineEdit.setGeometry(QtCore.QRect(28, 24, 113, 20))
        self.pushButton = QtGui.QPushButton(Form1)
        self.pushButton.setGeometry(QtCore.QRect(30, 68, 75, 23))
        self.pushButton.setText("Oeffne Dialog")
        self.lineEdit.setFocus()

        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), self.unterfenster_aufrufen)
 
    def unterfenster_aufrufen(self):
       app2 = QtGui.QApplication(sys.argv)
       Form2 = QtGui.QDialog()
       dlg = Unterfenster()
       dlg.setupUi(Form2)
       dlg.label.setText(self.lineEdit.text())
       dlg.pushButton.setText("Zurueck")
       Form2.show()
       self.lineEdit.setFocus()
       QtCore.QObject.connect(dlg.pushButton, QtCore.SIGNAL("clicked(bool)"), self.unterfenster_schliessen)

 
    def unterfenster_schliessen(self):
        Form1.setWindowTitle("Form2 closed")
#        Form2.close()  # hier an dieser Stelle habe ich schon alles 
#                                  moegliche ausprobiert - ohne Erfolg

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    Form1 = QtGui.QWidget()
    ui = Hauptfenster()
    Form1.show()
    sys.exit(app.exec_())

Und hier der Source für das Unterfenster (Dateiname: modul1.pyw)

Code: Alles auswählen

from PyQt4 import *

class Unterfenster(object):
   def setupUi(self, Form2):
       Form2.resize(350, 100)
       Form2.setWindowTitle("Unterfenster")
       self.label = QtGui.QLabel(Form2)
       self.label.setGeometry(QtCore.QRect(28, 18, 300, 23))
       self.pushButton = QtGui.QPushButton(Form2)
       self.pushButton.setGeometry(QtCore.QRect(24, 60, 75, 23))


Wo ist mein Fehler....was mache ich falsch ?
Kann mir jemand weiterhelfen ?

Vielen Dank


btw.
Unter PyQt3 war das alles so wunderbar einfach. Warum
konnte man da nicht einfach die Finger davon lassen ?
:cry:
lunar

Das hat mit Qt gar nichts zu tun, erst recht nicht mit dem Unterschied zwischen PyQt3 und PyQt4. Dir fehlen Python-Grundlagen. Lies doch bitte das Tutorial, und informiere Dich über Klassen. "Form2" ist ein lokaler Name, der nur in der Funktion existiert. Das Du darauf nicht mehr zugreifen kannst, sollte eigentlich logisch sein. Ebenso ist der Zugriff auf "Form1" in __init__ sehr abenteuerlich und alles andere als guter Stil.
ciclista
User
Beiträge: 3
Registriert: Samstag 16. Januar 2010, 16:09

lunar hat geschrieben:Das hat mit Qt gar nichts zu tun, erst recht nicht mit dem Unterschied zwischen PyQt3 und PyQt4. Dir fehlen Python-Grundlagen. Lies doch bitte das Tutorial, und informiere Dich über Klassen. "Form2" ist ein lokaler Name, der nur in der Funktion existiert. Das Du darauf nicht mehr zugreifen kannst, sollte eigentlich logisch sein. Ebenso ist der Zugriff auf "Form1" in __init__ sehr abenteuerlich und alles andere als guter Stil.
Das ist schlicht und einfach dummes Zeug was du da von dir gibst.
Zum einen hättest du meinem Kommentar im Quellcode entnehmen können, dass ich hier schon mehrer Möglichkeiten durchprobiert habe.
Ich habe das Form2.close() nur symbolisch stehen lassen.

Zum anderen programmeire ich schon etwas länger in Python/PyQt

Und last but not least funktionierte das unter PyQt3 völlig problemlos.
(gibt es leider nicht "offiziell" für Windows, sonst hätte ich diesen
Qt4-Mist schon längst wieder runtergeschmissen)


Merke:
Wenn du keine sinnvollen(geschweige denn irgendwie hilfreichen) Antworten geben kannst, halte doch bitte einfach nur den Mund :(
lunar

Wenn dem so ist, wünsche ich Dir viel Glück mit Deinem Problem :)
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

ciclista hat geschrieben:Merke:
Wenn du keine sinnvollen(geschweige denn irgendwie hilfreichen) Antworten geben kannst, halte doch bitte einfach nur den Mund :(
Merke:
Wenn das weiterhin dein Verständnis von Höflichkeit ist, wird lunar nicht der einzige sein, der seinen Mund hält. Ich habe bei dem Ton jedenfalls noch nicht einmal die Lust, dir überhaupt helfen zu wollen.




Edit: Ich halte, du hältst, er/sie/es hält, wir halten, ihr haltet, sie halten (Warum hat das keiner gemerkt?) :oops:
Zuletzt geändert von derdon am Montag 18. Januar 2010, 16:55, insgesamt 1-mal geändert.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

@ciclista: Denk doch mal 'ne Sekunde darüber nach, wie du dich hier benimmst: Du schreibst deinen ersten Post im Forum, bekommst detaillierte Informationen von jemandem, der weiß, wovon er spricht, und dir fällt nichts ein als Beschimpfungen. Peinlich. So wird das gewiss nichts.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Der ganze Code ist bei genauerem hinsehen, sehr abenteuerlich.

Dein "Hauptfenster" und "Unterfenster" sind keine Fenster, zumindest sind die von keinem abgeleitet.

Du benutzt keinerlei Layouts, der User darf sich also daran erfreuen was du als Fenstergröße und Schriftart/-größe gerade so toll findest.

Du veränderst globale Objekte innerhalb von Klassen, die deswegen gar nicht funktionieren können, wenn man sie importiert.

Dass du in Zeile 14 "Oeffne Dialog" verwendest statt u"Öffne Dialog" zeigt auch dass du von Unicode noch nichts gehört hast. Sobald du Text als Eingabe/Ausgabe hast sollte man sich mit der Thematik beschäftigen.

Du erzeugst ein neues QApplication Objekt in Hauptfenster.unterfenster_aufrufen, wo sich die Frage stellt ob du überhaupt weißt was dass ist.

Deine Bezeichner sind mal Deutsch, mal Englisch, mal ausgeschrieben, mal abgekürzt(ohne ersichtlichen Grund). Da man Englisch als Programmierer ohnehin kann und du damit keine Probleme mit Umlauten bekommst, solltest du dabei bleiben.

Das sieht so aus als ob du dass mit Qt3 auch nur konntest weil du auswendig gelernt hast, nicht weil du programmieren kannst. Die Ähnlichkeit zu einem Analphabeten ist da erstaunlich.

Am besten du liesst nochmal ein Python Tutorial und arbeitest ein PyQt4 Tutorial durch. Wenn sich Fragen stellen such mal hier im Forum oder schau dir die Beispiele von lunar hier an, die wie seine Posts i.d.R. sehr hilfreich und korrekt sind.
Benutzeravatar
Defnull
User
Beiträge: 778
Registriert: Donnerstag 18. Juni 2009, 22:09
Wohnort: Göttingen
Kontaktdaten:

lunar hat geschrieben:Das hat mit Qt gar nichts zu tun, erst recht nicht mit dem Unterschied zwischen PyQt3 und PyQt4. Dir fehlen Python-Grundlagen. Lies doch bitte das Tutorial, und informiere Dich über Klassen. "Form2" ist ein lokaler Name, der nur in der Funktion existiert. Das Du darauf nicht mehr zugreifen kannst, sollte eigentlich logisch sein. Ebenso ist der Zugriff auf "Form1" in __init__ sehr abenteuerlich und alles andere als guter Stil.
Mehr muss und will ich dazu auch nicht mehr sagen.
Bottle: Micro Web Framework + Development Blog
ciclista
User
Beiträge: 3
Registriert: Samstag 16. Januar 2010, 16:09

Auch ohne weitere dumme Kommentare.

Code: Alles auswählen

from PyQt4 import QtCore, QtGui

class Unterfenster(QtGui.QWidget):
    def __init__(self, parent=None):
        super(Unterfenster, self).__init__(parent)
        self.resize(350, 100)
        self.setWindowTitle("Unterfenster")
        self.label = QtGui.QLabel(self)
        self.label.setGeometry(QtCore.QRect(28, 18, 300, 23))
        closeButton = QtGui.QPushButton(self)
        closeButton.setGeometry(QtCore.QRect(24, 60, 75, 23))
        closeButton.setText("Zurueck")
        closeButton.clicked.connect(self.Unterfenster_schliessen)

    def Unterfenster_schliessen(self):
        Form1.lineEdit.clear()
        Form1.lineEdit.setFocus()
        self.close()

class Hauptfenster(QtGui.QWidget):
    def __init__(self):
        super(Hauptfenster, self).__init__()
        self.resize(256, 128)
        self.setWindowTitle("Dialogtest")
        self.lineEdit = QtGui.QLineEdit(self)
        self.lineEdit.setGeometry(QtCore.QRect(28, 24, 113, 20))
        OpenButton = QtGui.QPushButton(self)
        OpenButton.setGeometry(QtCore.QRect(30, 68, 75, 23))
        OpenButton.setText("Oeffne Dialog")
        CloseButton = QtGui.QPushButton(self)
        CloseButton.setGeometry(QtCore.QRect(150, 68, 75, 23))
        CloseButton.setText("Schliessen")
        self.lineEdit.setFocus()
        OpenButton.clicked.connect(self.Unterfenster_aufrufen)
        CloseButton.clicked.connect(self.close)

    def Unterfenster_aufrufen(self):
        Form2 = Unterfenster(self)
        Form2.label.setText(self.lineEdit.text())
        Form2.setWindowFlags(QtCore.Qt.Window)
        Form2.show()
 
if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form1 = Hauptfenster()
    Form1.show()
    sys.exit(app.exec_())
lupinix
User
Beiträge: 1
Registriert: Dienstag 30. Juni 2009, 16:26

ciclista hat geschrieben:

Code: Alles auswählen

from PyQt4 import QtCore, QtGui

class Unterfenster(QtGui.QWidget):

    def Unterfenster_schliessen(self):
        Form1.lineEdit.clear()
        Form1.lineEdit.setFocus()
        self.close()

 
if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form1 = Hauptfenster()
    Form1.show()
    sys.exit(app.exec_())
Also, was viele hier (inkl. mir) stört ist, dass du ein Objekt (Form1) innerhalb der Klassendeklaration verwendest, es aber im Hauptprogramm erzeugst.
Das Form1 gehört in eine Methode wie Unterfenster_schliessen nicht hinein. Das hat übrigens nicht nur mit sauberem Programmierstil, sondern vor allem (und in deinem eigenen Interesse hoofe ich) mit einen fehlerfreien Code zutun.
Mein Tipp: Arbeite dich mal in OOP ein, dein Code ähnelt meinem Frickelcode als ich mal anfangen wollte GUIs zu programmieren, aber noch keine Ahnung von OOP hatte. Unsaubere Zugriffe funktionieren zwar in vielen Fällen, aber
1. wenn das erstmal zur Gewohnheit wurde ist das irgendwie in einem drin
2. provoziert man Fehler die man dann garnicht als solche findet.

Im Übrigen: Niemand will dir hier was böses, ich (und ich denke auch so manch anderer) spriche da aus eigener Erfahrung. Auch wenn saubere OOP aufwendiger ist: Bei größeren Sachen wie GUIs kannst du ordentliche Probleme bekommen wenn du nicht aufpasst.

Viele Grüße
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Ich hab da auch noch etwas Senf zum Brötchen:

1. Dein Code läßt alles andere als vermuten, daß Du schon reichlich Erfahrung mit Python/PyQt hast. Warum? Der Zugriff über das globale Form1 ist abenteuerlich, viel Spaß bei größeren Projekten, wo die Aufgaben über mehrere Module und Entwickler verteilt sind. Und Dein Versuch, es mit Form2, das auch noch lokal ist, gleichsinnig zu tun, zeigt, daß Du weder von Namensräumen in Python noch gängigen Konzepten der OOP hinreichend Bescheid weißt. Darauf hat lunar hingewiesen. Auf weichen Konventionen wie PEP8 oder PyQt eigene Namensgebung will ich gar nicht erst rumreiten.

2. Dein neuerer Code macht was ganz anderes als Dein Orginal, da das Unterfenster vom Unterfenster selbst geschlossen wird. Gäbe es die Anforderung "Schliesse Unterfenster vom Hauptfenster aus" würde ich sagen "Setzen, 6". ;)

Zu Deinem verbalen Ausrutscher fällt mir eigentlich nur eine Frage ein, wie alt bist Du? SCNR :twisted:
fabi1511
User
Beiträge: 23
Registriert: Donnerstag 25. Juni 2009, 18:59

Warum benutzt du eigentlich QWidget als Basisklasse und nicht QDialog??

Code: Alles auswählen

        Form1.lineEdit.clear()
        Form1.lineEdit.setFocus()
Was mich (wie alle andren auch) an diesem Code stört, ist die Verwendung von lokalen Referenzen. Jedes QWidget (QDialog natürlich auch) hat von Haus aus die Methode QWidget.parentWidget(self), welche das übergeordnete Widget zurückgibt.

Un warum schlägst du dich überhaupt mit Callback-Funktionen rum, wenn Qt Signal-Slot unterstützt? ein aufrum, wie

Code: Alles auswählen

self.emit(SIGNAL("Fenster_wurde_geschlossen()"))
und eine anscließende Implementierung im Hauptfenster wäre eleganter
lunar

fabi1511 hat geschrieben:Was mich (wie alle andren auch) an diesem Code stört, ist die Verwendung von lokalen Referenzen.
Unsinn. Die Verwendung von lokalen Namen ist doch vollkommen ok. Das Problem ist, dass der OP eben keine lokalen Namen verwendet. "Form1" bezieht sich auf einen globalen Namen, der nur mehr oder weniger zufällig vorhanden ist!

Mit ".parentWidget(self)" hat das nichts zu tun. Die sollte man für diesen Zweck eh nicht nutzen.
Und warum schlägst du dich überhaupt mit Callback-Funktionen rum, wenn Qt Signal-Slot unterstützt?
Wo siehst Du denn da "Callback"-Funktionen?!
Antworten