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 widgetclass 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 widgetclass 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,