Search code examples
pythonqt-creatorpyqt5pyuic

Import custom widgets from .ui files in PyQt5


I want to use custom widgets created with QtCreator by importing directly the .ui file. Currently my code works fine when I use pyuic5 to create a .py file. But I want to be able to import my widgets directly from the .ui file. Some of the working code :

main.py

import MyWidget

MainWindowUI, MainWindowBase = uic.loadUiType('main.ui')

class mainGUIWindow(MainWindowUI, MainWindowBase):
     def __init__(self, mainWindow):
         QtWidgets.QMainWindow.__init__(self)
         self.setupUi(self)

         self.myWidget = MyWidget.Ui_Form()
         self.myWidget.setupUi(self)

MyWidget.py (generated via pyuic5 -x MyWidget.ui -o MyWidget.py)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(271, 201)
        # The rest of the widget is down here

Is there a way to use LoadUi() or something similar to avoid the use of pyuic ? What I have tried so far:

main.py

class mainGUIWindow(MainWindowUI, MainWindowBase):
    def __init__(self, mainWindow):
        QtWidgets.QMainWindow.__init__(self)
        self.setupUi(self) # contains a QFrame called 'frame'

        # Creation of myWidget
        self.wid = myWidget()

        # Adding myWidget to a layout
        hbox = QtWidgets.QHBoxLayout()
        hbox.addWidget(self.wid)
        self.frame.setLayout(hbox)


class myWidget(QtWidgets.QWidget):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        uic.loadUi('MyWidget.ui', self)

When I try to add my widget to a layout in my main window I get this error:

QWidget::setLayout: Attempting to set QLayout "" on QFrame "frame", which already has a layout


Solution

  • I found a solution for this problem even if it's not the ideal for me I think it can help others. I had to create a new class which inherits PyQt5.QtWidgets.QWidget during the __init__() of this widget, the loadUi() function is called to catch the widget.ui file.

    class mainGUIWindow(MainWindowUI, MainWindowBase):
        def __init__(self, mainWindow):
            QtWidgets.QMainWindow.__init__(self)
            self.setupUi(self)
    
            wid = myWidget()
    
            self.grid = QtWidgets.QGridLayout()
            self.grid.addWidget(wid,0,0)
            self.frame.setLayout(self.grid)
    
    
    class myWidget(QtWidgets.QWidget):
        def __init__(self):
            QtWidgets.QWidget.__init__(self)
            uic.loadUi('Widget1.ui', self)