[PyQt] Trouble with uic.loadUi and connectSlotsByName

David Boddie david at boddie.org.uk
Mon May 17 03:58:01 BST 2010


On Sat May 15 22:55:42 BST 2010, Peter O'Malley wrote:

> I've created a simple window in Designer but can't get the
> connectSlotsByName function to connect up the button correctly when I've
> loaded the UI with uic.loadUi. I can connect the button manually, or I can
> use pyuic and it works, but I can't for the life of me figure out why this
> won't connect. I've looked all through the mailing list archives and
> google, but no I can't find my way out of it.

It seems that you are doing something different in the two cases you
mention. In the case where you use pyuic, you import the generated module
and instantiate the class it contains. This is instantiated and you set up
the UI and connections with the setupUi() call.

> import testui
>
> class TestWindow (QtGui.QMainWindow):
>     def __init__(self):
>         QtGui.QMainWindow.__init__(self)
>         self.ui = testui.Ui_MainWindow()
>         self.ui.setupUi(self)
>         self.show()

Now, when you use the uic module, you are instantiating an instance of a
widget, not just a class containing boilerplate code to set up widgets and
connections.

> class TestWindow (QtGui.QMainWindow):
>     def __init__(self):
>         QtGui.QMainWindow.__init__(self)
>         self.ui = uic.loadUi("test.ui")
>         QtCore.QMetaObject.connectSlotsByName(self)
>         #self.ui.maxButton.clicked.connect(self.on_maxButton_clicked)
>         self.ui.show()

Calling QMetaObject.connectSlotsByName(self) won't help because ui isn't a
child object of self as far as Qt's object system is concerned. In any case,
ui now contains another QMainWindow instance and you don't really want that.

What you may be able to do is to use uic.loadUiType() instead:

class TestWindow(QtGui.QWidget):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        ui_class, widget_class = uic.loadUiType("test.ui")
        ui = ui_class()
        ui.setupUi(self)

Here, loadUiType() returns a class containing the code to set up the UI and
the class to use if you are going to derive a new class using multiple
inheritance. Instead, we just instantiate the UI class and call setupUi() to
set up the UI and connections. Just as with the pyuic approach, you don't
have to set up the connections with connectSlotsByName() because setupUi()
will do that.

I'm not sure if this approach is the way people typically do things with the
uic module. It's been a long time since I used it. Certainly, you have a lot
of freedom to try different approaches to get the result you want.

David


More information about the PyQt mailing list