PyQt und Pyside mögen sich nicht?

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

An welcher Stelle wird die Referenz gehalten?
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Also, das öffnen der "reinen" *-ui-Datei ist mit deinem Quelltext kein Problem, allerdings habe ich ein Problem ein Kompilat zu öffnen.

Code: Alles auswählen

from uic_fix import loadUi, loadUiType
from PySide import QtGui, QtCore
import ui_rc

class TestWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        UI_PATH = QtCore.QFile(":/ui_file/CustomDialog.ui")

        UI_PATH.open(QtCore.QFile.ReadOnly)
        self.ui_mdi = loadUi(UI_PATH), self
        UI_PATH.close()
        
        self.pushButton.clicked.connect(self.close)
        
if __name__ == '__main__':
    app = QtGui.QApplication([])
    w = TestWidget()
    print type(w)
    w.show()
    app.exec_()
Traceback:
Traceback (most recent call last):
File "D:\Dan\Python\xarphus_project\examples\minimal_example\jerch_test_pyside.py", line 19, in <module>
w = TestWidget()
File "D:\Dan\Python\xarphus_project\examples\minimal_example\jerch_test_pyside.py", line 12, in __init__
self.ui_mdi = loadUi(UI_PATH), self
File "D:\Dan\Python\xarphus_project\examples\minimal_example\uic_fix.py", line 23, in loadUi
form_cls, base_cls = loadUiType(filename)
File "D:\Dan\Python\xarphus_project\examples\minimal_example\uic_fix.py", line 11, in loadUiType
with open(filename, 'r') as f:
TypeError: coercing to Unicode: need string or buffer, PySide.QtCore.QFile found
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Sophus:
Hier ist die aktualisierte Version --> https://github.com/jerch/pyside-uicfix

Ja bisher geht nur das Laden per Dateinamen. Ich weiss gar nicht, was PyQts `uic.loadUi` da alles unterstützt, Du kannst das gerne zusammentragen, dann patche ich das nach.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@jerch: Ich habe mich eben ein wenig umgesehen. Ich fand dieses Forum. Hierbei wird im Zusammenhang von Maya 2014 debattiert. Aber im Wesentlichen versuchen die loadUI-Funktion zu überschreiben. Vielleicht kannst du was Nützliches daraus entnehmen. Aber die werkeln auch nur mit der reinen *.ui-Datei - nicht mit dem Kompilat. Und dann fand ich diese GitHub-Seite. Allerdings auch nur mit der reinen *.ui.Datei.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Dein erster Link macht es analog mit `loadUiType`. Der zweite Link kann nur `loadUi`.

Du musst mir im Prinzip nur sagen, welche Dateiangaben PyQt's `loadUi` alles kann. Oder zeig mir einfach, wie Du es mit PyQt bisher gemacht hast. Wahrscheinlich fehlen Pythons Dateiobjekt und Qts QFile bzw. QIODevice-Objekte als erlaubte Parameter.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Also, die kompilierte *.ui-Dateien habe ich immer wie folgt geladen:

Code: Alles auswählen

import sys
from PyQt4.QtCore import QFile
from PyQt4.QtGui import QDialog, QApplication
from PyQt4.uic import loadUi
import ui_rc

class MyCustomDialog(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        
        UI_PATH = QFile(":/ui_file/CustomDialog.ui")

        UI_PATH.open(QFile.ReadOnly)
        self.ui_form = loadUi(UI_PATH, self)
        UI_PATH.close()

def main():
    app = QApplication(sys.argv)
    window = MyCustomDialog()
    window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Sophus:
Qts und Pythons file like objects sollten jetzt auch funktionieren.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Wenn ich folgendes probiere:

Code: Alles auswählen

from PySide import QtGui, QtCore
from pyside_uicfix import loadUi, loadUiType
import ui_rc

class TestWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        UI_PATH = QtCore.QFile(":/ui_file/CustomDialog.ui")

        UI_PATH.open(QtCore.QFile.ReadOnly)
        myWidget  = loadUi(UI_PATH), self
        UI_PATH.close()

        layout = QtGui.QVBoxLayout()
        layout.addWidget(myWidget)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QtGui.QApplication([])
    w = TestWidget()
    w.show()
    app.exec_()
bekomme ich folgendes (Traceback):
Traceback (most recent call last):
File "D:\Dan\Python\xarphus_project\examples\minimal_example\main_test_pyside.py", line 21, in <module>
w = TestWidget()
File "D:\Dan\Python\xarphus_project\examples\minimal_example\main_test_pyside.py", line 16, in __init__
layout.addWidget(myWidget)
TypeError: 'PySide.QtGui.QBoxLayout.addWidget' called with wrong argument types:
PySide.QtGui.QBoxLayout.addWidget(tuple)
Supported signatures:
PySide.QtGui.QBoxLayout.addWidget(PySide.QtGui.QWidget, int = 0, PySide.QtCore.Qt.Alignment = 0)
EDIT: Wenn ich das Layout komplett weglasse, wird zwar ein Fenster erzeugt, jedoch nicht aus dem Kompilat, sondern ein eigenes. Denn es fehlen die beiden Widgets (Label und pushButton) in der *.ui-Datei.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Ok, ich ziehe meinen vorherigen Beitrag zurück.

Ich habe einen Flüchtigkeitsfehler in meinem Quelltext gemacht. Hier der richtige und funktionierende Quelltext:

Code: Alles auswählen

from PySide import QtGui, QtCore, QtUiTools
from pyside_uicfix import loadUi, loadUiType
import ui_rc

class TestWidget(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)

        UI_PATH = QtCore.QFile(":/ui_file/CustomDialog.ui")

        UI_PATH.open(QtCore.QFile.ReadOnly)
        myWidget = loadUi(UI_PATH, self)
        UI_PATH.close()

if __name__ == '__main__':
    app = QtGui.QApplication([])
    w = TestWidget()
    w.show()
    app.exec_()
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Allerdings habe ich ein kleines Problem mit den Widgets.

Code: Alles auswählen

from PySide import QtGui, QtCore, QtUiTools
from pyside_uicfix import loadUi, loadUiType
import ui_rc

class TestWidget(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)

        UI_PATH = QtCore.QFile(":/ui_file/CustomDialog.ui")

        UI_PATH.open(QtCore.QFile.ReadOnly)
        self.myWidget = loadUi(UI_PATH, self)
        UI_PATH.close()

        self.myWidget.pushButton.clicked.connect(self.close)

if __name__ == '__main__':
    app = QtGui.QApplication([])
    w = TestWidget()
    w.show()
    app.exec_()
Sobald ich versuche, über die self.myWidget-Referenz auf den pushButton zuzugreifen bekomme ich die Meldung, dass das TestWidget-Objekt das Attribut pushButton nicht besitzt. Immerhin bin ich so bei PyQt4 vorgegangen um auf die UI befindlichen Widgets zuzugreifen.
Traceback (most recent call last):
File "D:\Dan\Python\xarphus_project\examples\minimal_example\main_test_pyside.py", line 19, in <module>
w = TestWidget()
File "D:\Dan\Python\xarphus_project\examples\minimal_example\main_test_pyside.py", line 15, in __init__
self.myWidget.pushButton.clicked.connect(self.close)
AttributeError: 'TestWidget' object has no attribute 'pushButton'
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Sophus:
Ich hatte gehofft, um den Basisklassen-Hack herum zu kommen. Jetzt ist er wieder drin, damit sollten die Formklassen-Member sichtbar sein.

Edit: Funktioniert allerdings nicht mit Qt-Basisklassen, hmm. Muss ich nochmal investigieren...
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Hab das Problem mittels Übertragung der Methoden von der Formularklasse auf das aktuelle Widgetobjekt lösen können. Damit funktioniert es auch mit Objekten der Qt-Klassen direkt ala `loadUi('/path/to/uifile', QWidget())`.
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

Abseits von jerch habe ich mir erlaubt ein paar Tests zu machen. Bei PySide kann man die Veröffentlichungen der letzten Versionen einsehen und herunterladen. Ich setzte meine Tests bei PySide 1.2.0 an. Bei jedem Wechsel der Versionen wurden die vorherigen Versionen ordnungsgemäß deinstalliert.

Auf meiner Maschine ist derzeit Qt 4.8.6 und Python 2.7.10

Mit diesem Quelltext habe ich den Test gestartet:

Code: Alles auswählen

import sys
from PySide import QtCore, QtGui, QtUiTools
import ui_rc

class MyCustomDialog(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)

        loader = QtUiTools.QUiLoader()
        file = QtCore.QFile(":/ui_file/CustomDialog.ui")
        file.open(QtCore.QFile.ReadOnly)
        myWidget = loader.load(file, self)
        file.close()

        layout = QtGui.QVBoxLayout()
        layout.addWidget(myWidget)
        self.setLayout(layout)

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

if __name__ == '__main__':
    main()
PySide 1.2.0:
- Python-Interpreter hängt sich nicht auf, jedoch wird das Kompilat nicht geladen. PySide kreiert sein eigenes Fenster.

PySide 1.2.1:
-Python-Interpreter hängt sich auf.

PySide 1.2.2:
- Python-Interpreter hängt sich auf

Python 1.2.3:
- konnte nicht gefunden werden

Python 1.2.4:
- Python-Interpreter hängt sich auf
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@jerch: Ich kann nun den pushButton ansprechen. Es klappt. Ich werde mein Projekt zunächst separat auf PySide umsatteln und mal schauen, ob es Probleme geben wird. An dieser Stelle ein dickes Dankeschön.

P.S. Vielleicht könntest du das der PySide-Community mitteilen und denen deine Arbeit vorlegen? Oder ist es mal wieder nur ein spezielles Sophus-Problem?
Benutzeravatar
Sophus
User
Beiträge: 1109
Registriert: Freitag 25. April 2014, 12:46
Wohnort: Osnabrück

@jerch: Eine weitere Frage bezüglich deines Patches. Ist dein Patch Version-Abhängig? Das heißt, sollte ich mich eines Tages (so schnell wird es nicht passieren) dazu entscheiden von Python 2.7.10 auf Python 3 zu wechseln und von Qt4 auf Qt5, wäre dein Patch dann immer noch kompatible?
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

@Sophus:
Ich hab den Code mal Python2/3 kompatibel gemacht. Qt5 geht nicht, da PySide kaum noch entwickelt wird, seit Digia Qt gekauft hat. PyQt ist da die bessere Wahl.
Antworten