Komme im Tutorial "PyQT by example" nicht weiter

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Freitag 11. Februar 2011, 15:26

Hallo, ich bin dabei das Tutorial "PyQT by Example" durchzuarbeiten.

Das Übungsprogramm ist eine Todo-liste. Dazu wird der QT-Designer verwendet.
Abweichend vom Tutorial lade ich die *ui Files dynamisch.


Ich stecke in Session 5.

Zum Anlegen eines neuen Todo-Eintrages soll ein selbst erstelltes Widget
ins Hauptfenster eingeblendet werden.

Ich schaffe es nicht dieses selbsterstellte Widget mit dem Platzhalterwidget zu verknüpfen.

Das Projekt besteht aus folgenden Dateien:

todo.py = kümmert sich um die Daten
main.py = Das Programm selbst
editor.py = ruft das selbsterstellte Widget auf, soll später Funktionen zum Editieren von Todo-Einträgen aufnehmen

window.ui= das Hauptfenster
editor.ui = das selbsterstellte Widget


Fehlermeldung beim Starten von main.py:

Code: Alles auswählen

Traceback (most recent call last):
  File "main.py", line 77, in <module>
    main()
  File "main.py", line 70, in main
    window = MyMainWindow()
  File "main.py", line 26, in __init__
    self.ui = uic.loadUi(ui_file, self)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/__init__.py", line 177, in loadUi
    return DynamicUILoader().loadUi(uifile, baseinstance)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/Loader/loader.py", line 24, in loadUi
    return self.parse(filename, os.path.dirname(filename))
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 842, in parse
    actor(elem)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 689, in createUserInterface
    self.traverseWidgetTree(elem)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 667, in traverseWidgetTree
    handler(self, child)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 169, in createWidget
    self.traverseWidgetTree(elem)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 667, in traverseWidgetTree
    handler(self, child)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 403, in createLayout
    self.traverseWidgetTree(elem)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 667, in traverseWidgetTree
    handler(self, child)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 446, in handleItem
    self.traverseWidgetTree(elem)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 667, in traverseWidgetTree
    handler(self, child)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 169, in createWidget
    self.traverseWidgetTree(elem)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 667, in traverseWidgetTree
    handler(self, child)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 163, in createWidget
    self.stack.push(self.setupObject(widgetClass(elem), parent, elem))
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/uiparser.py", line 135, in setupObject
    obj =  self.factory.createQObject(clsname, name, args, is_attribute)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/objcreator.py", line 67, in createQObject
    return self._cpolicy.instantiate(classType, *args, **kwargs)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/Loader/qobjectcreator.py", line 71, in instantiate
    return clsObject(*ctor_args)
  File "/home/seko/projekte/pyqt_by_example/ralsina-pyqt-by-example-46ebe52/session1/editor.py", line 24, in __init__
    self.ui = uic.loadUi(ui_file, self)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/__init__.py", line 177, in loadUi
    return DynamicUILoader().loadUi(uifile, baseinstance)
  File "/usr/lib/pymodules/python2.6/PyQt4/uic/Loader/loader.py", line 24, in loadUi
    return self.parse(filename, os.path.dirname(filename))
  File "/usr/lib/python2.6/posixpath.py", line 119, in dirname
    i = p.rfind('/') + 1
AttributeError: 'QSplitter' object has no attribute 'rfind'
Grüße aus der Schweiz
lunar

Freitag 11. Februar 2011, 16:15

"uic" erwartet bei benutzerdefinierten Steuerelementen, dass der Konstruktor nur ein Argument, nämlich "parent" hat. Bei "Editor.__init__()" ist das nicht der Fall. Es erscheint mir allerdings auch reichlich sinnfrei, den Dateinamen der Oberflächenbeschreibung als Argument zu übergeben.
Benutzeravatar
Mr_Snede
User
Beiträge: 387
Registriert: Sonntag 8. Februar 2004, 16:02
Wohnort: D-Dorf, Bo

Freitag 11. Februar 2011, 17:31

Danke, du hast mir den richtigen Hinweis gegeben.
Mal ganz dumm gefragt, hast du das alleine aus der Fehlermeldung gesehen, oder war das eher ein Efahrungswert?


editor.py sieht nun folgendermaßen aus:

Code: Alles auswählen

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

"""A custom widget that edits a task's properties"""

import sys
import os
from PyQt4 import QtCore, QtGui, uic

class editor(QtGui.QWidget):
    def __init__(self, parent, task=None):
        super(editor, self).__init__(parent)
        self.ui = uic.loadUi("editor.ui", self)


def main():
    app = QtGui.QApplication(sys.argv)
    window = editor()
    window.show()
    app.exec_()


if __name__ == '__main__':
    main()
lunar

Freitag 11. Februar 2011, 17:50

Ich habe das aus der Kombination aus Fehlermeldung und Quelltext geschlossen. Die letzten Zeilen des Tracebacks zeigt auf, dass das erste Argument von ".loadUi()" offensichtlich nicht dem erwarteten Typen entspricht, sondern ein Objekt vom Typ "QSplitter" ist. Der Quelltext offenbart dann, dass dieses Argument direkt aus dem ersten Argument von "Editor.__init__()" kommt. Dieser Konstruktor wiederum wird vom "uic"-Modul aufgerufen. Es liegt also nahe, dass "uic" einfach erwartet, dass diese Methode nur ein Argument, nämlich das Vater-Objekt, entgegen nimmt, und deswegen dort das entsprechende QSplitter-Objekt übergibt. Dazu passt auch, dass QSplitter ein Steuerelement ist, welches andere Steuerelemente enthält, und somit typischerweise oft als Vater an andere Steuerelemente übergeben wird.
Antworten