Расположение виджетов в QGridLayout?

Я хочу вот такое окно себе, но когда я добавляю кнопку далее она изменяет размер строк и столбцов автоматом.

Как сделать так, чтобы она просто была по центру своей ячейки, как на скрине и второе как мне объединить 'Введите текст' и строку ввода, чтобы они были в одной ячейки по центру как на скрине.
Этот скрин я сделала в paint, чтобы было видно как я хочу.

from PyQt5.QtWidgets import *
from PyQt5.QtCore import Qt

class EgoDialog(QWidget):
    def __init__(self):
        super().__init__()

        self.resize(500, 500)

        self.labl = QLabel('Введите текст:')
        self.ed = QLineEdit()

        self.frame = QFrame()
        self.frame.setStyleSheet('background-color: red;')
        self.frame2 = QFrame()
        self.frame2.setStyleSheet('background-color: red;')
        self.frame3 = QFrame()
        self.frame3.setStyleSheet('background-color: red;')

        self.frame5 = QFrame()
        self.frame5.setStyleSheet('background-color: red;')
        self.frame6 = QFrame()
        self.frame6.setStyleSheet('background-color: red;')
        self.frame7 = QFrame()
        self.frame7.setStyleSheet('background-color: red;')
        self.frame8 = QFrame()
        self.frame8.setStyleSheet('background-color: red;')
        self.frame9 = QFrame()
        self.frame9.setStyleSheet('background-color: red;')
        self.frame111 = QFrame()
        self.frame111.setStyleSheet('background-color: rgb(255, 255, 255);')
        self.btn = QPushButton('далее')
        self.btn.setFixedSize(80, 30)



        self.grid = QGridLayout()
        self.setLayout(self.grid)

        self.grid.addWidget(self.frame, 0, 0)
        self.grid.addWidget(self.frame2, 0, 1)
        self.grid.addWidget(self.frame3, 1, 0)
        self.grid.addWidget(self.frame111, 1, 1)
        self.grid.addWidget(self.labl, 1, 1, alignment=Qt.AlignCenter)
        self.grid.addWidget(self.frame5, 0, 2)
        self.grid.addWidget(self.frame6, 1, 2)
        self.grid.addWidget(self.frame7, 2, 0)
        self.grid.addWidget(self.frame8, 2, 1)
        self.grid.addWidget(self.frame9, 2, 2)
        self.grid.addWidget(self.btn, 2, 2)
        self.grid.setRowStretch(0, 1)
        self.grid.setRowStretch(1, 3)
        self.grid.setRowStretch(2, 1)
        self.grid.setColumnStretch(0, 2)
        self.grid.setColumnStretch(1, 5)
        self.grid.setColumnStretch(2, 2)


if __name__ == '__main__':
    app = QApplication([])
    win = EgoDialog()
    win.show()
    app.exec_()

Ответы (2 шт):

Автор решения: Sergey Tatarincev

Вы можете установить минимальный размер для строки/столбца

self.grid.setRowMinimumHeight(2,50)
self.grid.setColumnMinimumWidth(2,100)

Но в общем и целом это подход не совсем верный. Лучшим решением было бы добавить в ваш QGridLayout еще один компоновщик и вашу кнопку положить уже в него:

self.sublayout = QVBoxLayout()
self.sublayout.addStretch(1)
self.sublayout.addWidget(self.btn)
self.sublayout.addStretch(1)
self.grid.addLayout(self.sublayout, 2, 2)
self.setLayout(self.grid) 
#self.grid.addWidget(self.frame9, 2, 2) - естественно это убрать
→ Ссылка
Автор решения: S. Nick

Как вариант:

from PyQt5.QtCore import QSize, Qt
from PyQt5.QtWidgets import ( QApplication, QGridLayout, 
    QFormLayout, QLabel, QMainWindow, QStyle, QWidget, QFrame, 
    QLineEdit, QVBoxLayout, QPushButton)


class CentralWidget(QWidget):
    def __init__(self, widget):
        super().__init__()
        self._widget = widget
        self.widget.setParent(self)

    @property
    def widget(self):
        return self._widget

    def resizeEvent(self, event):
        super().resizeEvent(event)
        size = min(self.width(), self.height())
        r = QStyle.alignedRect(
            Qt.LeftToRight, Qt.AlignCenter, QSize(size, size), self.rect()
        )
        self.widget.setGeometry(r)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        
        container = QWidget()
        container.setStyleSheet('background-color: #FDBA9A;')
        
        container.setObjectName('container')
        central_widget = CentralWidget(container)
        self.setCentralWidget(central_widget)

        lay = QGridLayout(container)
        lay.setSpacing(0)
        lay.setContentsMargins(0, 0, 0, 0)

        self.listFrames = []
        
        for i in range(3):
            for j in range(3):
                frame = QFrame()            
                frame.setObjectName(f"Frame {i} {j}")
                label = QLabel(f"Frame {i} {j}", alignment=Qt.AlignCenter)
                label.setStyleSheet(
                    "background-color: #FDBA9A;"
                    if i == 1 and j == 1
                    else "border: 0.1em solid black; background: #C81912;"
                )
                layout = QGridLayout(frame)
                layout.setContentsMargins(1, 1, 1, 1)
                
                if i == 1 and j == 1:
                    self.labl = QLabel('Введите текст:')
                    self.ed = QLineEdit() 
                    fr = QFrame()
                    fr.setObjectName(f"Frame !!!")
                    vlayout = QVBoxLayout(fr)
                    flayout = QFormLayout()
                    flayout.addRow(self.labl, self.ed)
                    fr.setStyleSheet('background-color: #D1E8E4;')
                    vlayout.addLayout(flayout)
                    layout.addWidget(fr, 0, 0, alignment=Qt.AlignCenter)
                    self.listFrames.append(fr)                    
                elif i == 2 and j == 2:
                    self.pushButton = QPushButton('далее', label)
                    self.pushButton.clicked.connect(self.on_clicked)
                    self.pushButton.setStyleSheet('background-color: #D1E8E4;')
                    self.pushButton.setFixedSize(80, 30)
                    vlayout = QVBoxLayout(label)
                    vlayout.addWidget(self.pushButton)
                    
                    layout.addWidget(label)
                    self.listFrames.append(frame)
                else:             
                    layout.addWidget(label)  
                    self.listFrames.append(frame)
                
                lay.addWidget(frame, i, j)
            
        lay.setColumnStretch(0, 1)
        lay.setColumnStretch(1, 3)
        lay.setColumnStretch(2, 1)
        lay.setRowStretch(0, 1)
        lay.setRowStretch(1, 3)
        lay.setRowStretch(2, 1)
        
    def on_clicked(self):
        print(f'Вы ввели текст: {self.ed.text()}')
        
        #for i in self.listFrames:
        #    print(i.objectName())
        

def main():
    app = QApplication([])
    app.setStyle("fusion")
    view = MainWindow()
    view.setMinimumSize(510, 510)
    view.show()
    app.exec_()


if __name__ == "__main__":
    main()

введите сюда описание изображения

→ Ссылка