jgsedi
jgsedi

Reputation: 247

How to insert a custom PyQt5-widget with own layout in another widget with layout?

I wrote a custom widget with a "QHBoxLayout". If I use that widget in a base widget with a "QGridLayout" my widget will not be inserted correctly.

It doesn't matter when my widget is inserted in the PyQtWindow - all possibilities leading to a layout mismatch.

To change the order of the two statements addLayout and addWidget in the method _insert_mywidget of PyQtWindow shows also no effect.

Here the code example:

import sys
from PyQt5.QtWidgets import \
    QWidget, QApplication, \
    QHBoxLayout, QGridLayout, \
    QLineEdit, QLabel


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

        layout = QHBoxLayout()
        self.setLayout(layout)

        self.edits = [QLineEdit(self) for _ in range(3)]
        for edit in self.edits:
            layout.addWidget(edit)


class PyQtWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Layouttest")

        # GUI (layout and 3 rows in a grid)

        layout = QGridLayout()
        self.setLayout(layout)

        self._insert_mywidget(layout)
        # insert at first

        self.labels = [QLabel("Label " + str(i+1)) for i in range(5)]
        for i, label in enumerate(self.labels):
            layout.addWidget(label, 1, i)

        # self._insert_mywidget(layout)
        # insert at 2nd

        self.edits = [QLineEdit(self) for _ in range(10)]
        for i, edit in enumerate(self.edits):
            layout.addWidget(edit, 2, i)

        # self._insert_mywidget(layout)
        # insert at last

    def _insert_mywidget(self, layout):
        self.widget = MyWidget(self)

        # add my widget
        layout.addWidget(self.widget, 0, 0, 0, 10)

        # add layout from widget
        layout.addLayout(self.widget.layout(), 0, 0, 0, 10)


# ###
# run app

app = QApplication(sys.argv)

window = PyQtWindow()
window.show()

sys.exit(app.exec_())

Upvotes: 3

Views: 1781

Answers (2)

jgsedi
jgsedi

Reputation: 247

Ok the point is to insert a '1' in the method layout.addWidget(self.widget, 0, 0, 1, 10). This gets the expected result. To create a self.layout attribute isn't necessary (@S. Nick).

Then the method _insert_mywidget(self, layout): is now:

def _insert_mywidget(self, layout):
    self.widget = MyWidget(self)

    # to insert a columnspan at least one row must be is necessary
    layout.addWidget(self.widget, 0, 0, 1, 10)

thanks to @ekhumoro and @S.Nick

Upvotes: 0

S. Nick
S. Nick

Reputation: 13691

Try it:

import sys
from PyQt5.QtWidgets import ( QWidget, QApplication, QHBoxLayout, 
                              QGridLayout, QLineEdit, QLabel)


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

        layout = QHBoxLayout()
        self.setLayout(layout)

        self.edits = [QLineEdit(self) for _ in range(3)]
        for edit in self.edits:
            layout.addWidget(edit)


class PyQtWindow(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("Layouttest")

        self.layout = QGridLayout()                                   # + self.layout
        self.setLayout(self.layout)

        self._insert_mywidget()                                       # - (layout)

        self.labels = [QLabel("Label " + str(i+1)) for i in range(5)]
        for i, label in enumerate(self.labels):
            self.layout.addWidget(label, 1, i)

        self.edits = [QLineEdit(self) for _ in range(10)]
        for i, edit in enumerate(self.edits):
            self.layout.addWidget(edit, 2, i)

    def _insert_mywidget(self):                                        # - , layout):
        self.widget = MyWidget(self)

        # add my widget
#        self.layout.addWidget(self.widget, 0, 0, 0, 10)   
        self.layout.addWidget(self.widget, 0, 0, 1, 10)                # + 1

#        layout.addLayout(self.widget.layout(), 0, 0, 0, 10)


app = QApplication(sys.argv)

window = PyQtWindow()
window.show()

sys.exit(app.exec_())

enter image description here

Upvotes: 4

Related Questions