How do I load children from .ui file in PySide?

2019-02-24 22:48发布

问题:

For now I'm loading them like this:

if __name__ == '__main__':
    app = QApplication(sys.argv)
    loader = QUiLoader()
    file = QFile('main.ui')
    file.open(QFile.ReadOnly)
    window = loader.load(file)
    file.close()
    window.show()
    # Here:
    window.centralwidget.findChild(QListWidget, 'listWidget').addItems(['Item {0}'.format(x) for x in range(100)])
    sys.exit(app.exec_())

But I think it's uncomfortably, is there any other way, probably to load whole namespace or whatever?

回答1:

At the moment, the PySide QUiLoader class doesn't have a convenient way to load widgets into to an instance of the top-level class like the PyQt uic module has.

However, it's fairly easy to add something equivalent:

from PySide import QtGui, QtCore, QtUiTools

class UiLoader(QtUiTools.QUiLoader):
    _baseinstance = None

    def createWidget(self, classname, parent=None, name=''):
        if parent is None and self._baseinstance is not None:
            widget = self._baseinstance
        else:
            widget = super(UiLoader, self).createWidget(classname, parent, name)
            if self._baseinstance is not None:
                setattr(self._baseinstance, name, widget)
        return widget

    def loadUi(self, uifile, baseinstance=None):
        self._baseinstance = baseinstance
        widget = self.load(uifile)
        QtCore.QMetaObject.connectSlotsByName(widget)
        return widget

Which could then used like this:

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(self, parent)
        UiLoader().loadUi('main.ui', self)
        self.listWidget.addItems(['Item {0}'.format(x) for x in range(100)])

For this to work properly, the baseinstance argument of loadUi has to be an instance of the top-level class from Qt Designer file. All the other widgets will then be added to it as instance attributes.