Die verrückten Layouts im QT Designer

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Hallo Leute,

irgendwie scheint mir das modulare Arbeiten mit den *.ui-Dateien nicht ganz zu funktionieren.

Wichtige Informationen: Dateien für das Beispiel-Projekt.

- push_button.ui
- text_edit.ui
- ui.qrc
- ui_rc.py

Für diejenigen, die das gesamte Beispiel in einem Rutsch laden wollen, hier die *.zip-Datei.

Szenario:
Nun, ich habe hier drei Klassen, einmal Combine_Window (in main_project.py), PushButton_Window (in frm_push_button_window.py) und TextEdit_Window (in frm_text_edit_window). In der Combine_Window()-Klasse werden die letzten beiden Klassen instanziiert. Anschließend werden die instanziierten Klassen in ein horizontales Layout gesetzt. In den Klassen PushButton_Window und TextEdit_Window werden jeweilige *ui-Dateien aus der Ressourcen-Dateien geladen. Sobald ich das Beispiel ausführe, und die Combine_Window()-Klasse starte, bekomme ich eine Fehlermeldung - Siehe am Ende des Beitrages.

main_project.py

Code: Alles auswählen

#!/usr/bin/env python
#-*- coding:utf-8 -*-

FILE_NAME = "main_project.py"

import os
import sys
import time


from PyQt4.QtGui import QApplication, QVBoxLayout, QWidget

from frm_push_button_window import PushButton_Window
from frm_text_edit_window import TextEdit_Window
import ui_rc
 
class Combine_Window(QWidget):
    def __init__(self):
        super(Combine_Window, self).__init__()

        self.form_widget_buttons = PushButton_Window(self)
        self.form_widget_textedit = TextEdit_Window(self)
        layout = QVBoxLayout()
        layout.addLayout(self.form_widget_buttons)
        layout.addLayout(self.form_widget_textedit)
        self.setLayout(layout)

app = QApplication([])
foo = Combine_Window()
foo.show()
sys.exit(app.exec_())
frm_push_button_window.py

Code: Alles auswählen

#!/usr/bin/env python
#-*- coding:utf-8 -*-

FILE_NAME = "frm_push_button_window.py"

import os
import sys

from PyQt4.QtCore import Qt, QFile
from PyQt4.uic import loadUi
from PyQt4.QtGui import QWidget


BASE_PATH = os.path.dirname(os.path.abspath(__file__))

class PushButton_Window(QWidget):
    def __init__(self, parent):

        QWidget.__init__(self, parent)

        UI_PATH = QFile(":/ui_file/push_button.ui")

        try:
            UI_PATH.open(QFile.ReadOnly)
            self.ui_create_user = loadUi(UI_PATH, self)
            UI_PATH.close()
            print "STATUS [OK]  (", FILE_NAME, "): GUI is loaded from PyQt4"
        except Exception as ex:
            print "STATUS [FAILED]  (", FILE_NAME, "):", ex
        except:
            print "STATUS [FAILED]  (", FILE_NAME, "): Unexpected error:", sys.exc_info()[0]
            raise


    def closeEvent(self, event):
        pass
frm_text_edit_window.py

Code: Alles auswählen

#!/usr/bin/env python
#-*- coding:utf-8 -*-

FILE_NAME = "frm_push_button_window.py"

import os
import sys

from PyQt4.QtCore import Qt, QFile
from PyQt4.uic import loadUi
from PyQt4.QtGui import QWidget

BASE_PATH = os.path.dirname(os.path.abspath(__file__))

class TextEdit_Window(QWidget):
    def __init__(self, parent):

        QWidget.__init__(self, parent)

        UI_PATH = QFile(":/ui_file/text_edit.ui")

        try:
            UI_PATH.open(QFile.ReadOnly)
            self.ui_create_user = loadUi(UI_PATH, self)
            UI_PATH.close()
            print "STATUS [OK]  (", FILE_NAME, "): GUI is loaded from PyQt4"
        except Exception as ex:
            print "STATUS [FAILED]  (", FILE_NAME, "):", ex
        except:
            print "STATUS [FAILED]  (", FILE_NAME, "): Unexpected error:", sys.exc_info()[0]
            raise


    def closeEvent(self, event):
        pass
Fehlermeldung
Traceback (most recent call last):
File "D:/Dan/Python/xarphus/test_project/main_project.py", line 29, in <module>
foo = FirstWindow()
File "D:/Dan/Python/xarphus/test_project/main_project.py", line 24, in __init__
layout.addLayout(self.form_widget_buttons)
TypeError: QBoxLayout.addLayout(QLayout, int stretch=0): argument 1 has unexpected type 'PushButton_Window'
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Sophus:
Steht doch in der Fehlermeldung: addLayout erwartet einen Typen QLayout, das sind Deine Widgets aber nicht.

Deine Fehlerbehandlung in den Widgetklassen ist unsinnig - Du fängst alle Fehler, um sie per print auszugeben, sorgst aber nicht dafür, dass das Programm nach Fehler noch in einem gültigen Zustand ist. Dann brauchst Du die Fehlerbehandlung nicht, da unbehandelte Fehler ja schon ausgebenen werden und Du damit "debuggen" kannst.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Sophus: zusätzlich zu dem was jerch schon zu Deinem Code gesagt hat, hier noch ein paar Anmerkungen:
- nicht jede Python-Datei braucht eine Shebang-Zeile, sondern nur solche, die auch tatsächlich zum Ausführen gedacht sind
- FILE_NAME selbst zu definieren ist überflüssig, weil der Dateiname schon in __file__ steht.
- ach __file__ kennst Du schon, aber BASE_PATH wird nirgends benutzt, kann also weg
- UI_PATH ist keine Konstante, sollte also auch nicht wie eine geschrieben werden
- für log-Ausgaben gibt es das Modul logging, das Du statt Deiner print benutzen solltest
- was ist an einer allgemeinen Exception erwartet, erwartest Du in Deinem Programm etwa NameErrors?
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@jerch: Wenn ich dich richtig verstanden habe, dann meinst du, ich solle an statt die addLayout()-Methode die addWidget()-Methode benutzen?

@Sirius3: Ich werde die Bemerkungen berücksichtigen.

Vielen Dank euch.
Antworten