Question about using UI/xml files from Qt designer in Pyside



  • Using Pyside I am able to load and run ui files created in qt designer. I forget the source so forgive me for not giving credit but I use this class to facilitate loading the ui file.

    The reason I am trying to do this with ui files is because I have a lot of complex forms to create with a lot of trial and error and it has been very easy to modify in designer and just save.

    @from PySide.QtUiTools import QUiLoader
    class UiLoader(QUiLoader):

    def __init__(self, baseinstance):
        QUiLoader.__init__(self, baseinstance)
        self.baseinstance = baseinstance
    
    def createWidget(self, class_name, parent=None, name=''):
        if parent is None and self.baseinstance:
            # supposed to create the top-level widget, return the base instance instead
            return self.baseinstance
        else:
            # create a new widget for child widgets
            widget = QUiLoader.createWidget(self, class_name, parent, name)
            if self.baseinstance:
                # set an attribute for the new child widget on the base
                # instance, just like PyQt4.uic.loadUi does.
                setattr(self.baseinstance, name, widget)
            return widget@
    

    That is saved to a file called UiLoader.py and is brought in with 'from UiLoader import *.

    Then I have a function in my script to setup a loader.

    @def loadUi(uifile, baseinstance=None):
    loader = UiLoader(baseinstance)
    widget = loader.load(uifile)
    QMetaObject.connectSlotsByName(widget)
    return widget@

    The basic script looks like this.

    @#!/usr/bin/env python

    import os
    import sys
    from PySide.QtCore import *
    from PySide.QtGui import *
    from UiLoader import *

    def loadUi(uifile, baseinstance=None):
    loader = UiLoader(baseinstance)
    widget = loader.load(uifile)
    QMetaObject.connectSlotsByName(widget)
    return widget

    class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        loadUi(ResDir + '/mainwindow.ui', self)
    

    def main():
    global ResDir
    ResDir = os.path.dirname(os.path.realpath(file)) + "/resources"
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

    if name == 'main':
    main()@

    The problem I am having is loading additional forms. I need to be able to bring up other forms through events in the main window. This is what I tried.

    @#!/usr/bin/env python

    import os
    import sys
    from PySide.QtCore import *
    from PySide.QtGui import *
    from UiLoader import *

    def loadUi(uifile, baseinstance=None):
    loader = UiLoader(baseinstance)
    widget = loader.load(uifile)
    QMetaObject.connectSlotsByName(widget)
    return widget

    class MainWindow(QMainWindow):

    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        loadUi(ResDir + '/mainwindow.ui', self)
        self.pshRunOptions.clicked.connect(self.runOptions)
    
    def runOptions(self):
        loadUi(ResDir + '/runoptions.ui', self)
        window = runoptions()
        window.show()
    

    class runoptions(QWidget):

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        loadUi('resources/runoptions.ui', self)
    

    def main():
    global ResDir
    ResDir = os.path.dirname(os.path.realpath(file)) + "/resources"
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    app.exec_()

    if name == 'main':
    main()@

    It sort of works but I get warnings returned and it changes the main window.

    Here are the warnings.

    bq. Designer: Attempt to add a layout to a widget 'Dialog' (MainWindow) which already has a layout of non-box type QMainWindowLayout.
    This indicates an inconsistency in the ui-file.
    Object::connect: No such slot runoptions::accept()
    Object::connect: (sender name: 'buttonBox')
    Object::connect: (receiver name: 'Dialog')
    Object::connect: No such slot runoptions::reject()
    Object::connect: (sender name: 'buttonBox')
    Object::connect: (receiver name: 'Dialog')

    Frankly, this is new territory for me and I have no idea what I'm doing. There may be a better approach entirely. If someone knows an easy fix to my code it would be much appreciated.

    Cheers,



  • I think I solved this. I was calling loadUi in the function call. That was not needed because the call to loadUi was already defined in the runoptions class.

    Silly me.

    I am still getting this error;

    bq. Object::connect: No such slot runoptions::accept()
    Object::connect: (sender name: ‘buttonBox’)
    Object::connect: (receiver name: ‘Dialog’)
    Object::connect: No such slot runoptions::reject()
    Object::connect: (sender name: ‘buttonBox’)
    Object::connect: (receiver name: ‘Dialog’)

    The 'runoptions' form contains an OK and Cancel button which do not work. Not sure how to fix that but at least I am making some progress.

    I am not getting the "Designer" error anymore.
    Cheers,


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.