Search code examples
pythonpyqtqwidget

How to insert a Qwidget inside Qwidget


I am lost with all the parenting/initialising issues and have no idea why this does not work. So I create a Label, then I create another Label with some painting in it, them I make a widget that contains the two, then I would like to put this new widget inside the main window... but nothing appears

import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class Labhtml(QLabel):

    def __init__(self):
        super().__init__()

        label = QLabel('html')


class Bar(QLabel):

    def __init__(self):
        super().__init__()

        self.resize(100, 5)

    def paintEvent(self, e):
        qp = QPainter(self)
        qp.setBrush(QColor(200, 0, 0))
        qp.drawRect(0,0,200,3)


class Wid(QWidget):
    def __init__(self, parent):
        super().__init__(parent=parent)

        widget = QWidget()
        html = Labhtml()
        bar = Bar()

        self.layout = QVBoxLayout(widget)
        self.layout.addWidget(html)
        self.layout.addWidget(bar)


class Example(QScrollArea):
    def __init__(self):
        super().__init__()

        widget = QWidget()
        layout = QVBoxLayout(widget)

        layout.addWidget(Wid(widget))

        self.setWidget(widget)
        self.setWidgetResizable(True)

        self.show()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

Solution

  • First for the class Labhtml, when you inherit from QLabel, you can use the methods and the attributes of the base class, or use the instantiation mechanism to pass some parameters :

    class Labhtml(QLabel):
    
        def __init__(self):
            super().__init__()
            self.setText('html')
    

    Then you don't need to create another widget inside the Wid class, but you have to refer to self instead :

    class Wid(QWidget):
        def __init__(self, parent):
            super().__init__(parent=parent)
    
            html = Labhtml()
            bar = Bar()
    
            self.layout = QVBoxLayout(self)
            self.layout.addWidget(html)
            self.layout.addWidget(bar)
    

    About the instantiation mechanism you could also write the classes by declaring a new text argument (the same used for the Qlabel), and pass it when you create your instance :

    class Labhtml(QLabel):
    
        def __init__(self, text):
            super().__init__(text)
    
    
    class Wid(QWidget):
        def __init__(self, parent):
            super().__init__(parent=parent)
    
            html = Labhtml('html')