сохранить виджет макета сетки как квадрат
Это должно быть легко, но я все больше и больше сбиваюсь с толку, глядя на предлагаемые ответы, которые не работают. Все, что я хочу сделать, это иметь возможность иметь кучу виджетов в макете сетки, где изменение размера окна приведет к изменению размера виджетов внутри сетки, чтобы заполнить пространство, где это возможно, но сохранить их соотношение сторон (квадрат в данном случае как это сетка из квадратов 2x2).
Вот код без каких-либо моих неудачных попыток сделать это. Изначально я планировал ограничить само окно фиксированным соотношением сторон, но не смог заставить это работать. Я соглашусь на фрейм (или другой виджет / макет), имеющий эту функцию. Предельный размер квадрата не важен, пока он растягивается и сжимается вместе с окном, сохраняя при этом квадратное содержимое. Здесь я использую PySide6, но решение с PyQt5 подойдет. C++, хотя и не очень, я в нем грамотный. Требуется ли индивидуальная обработка изменения размера? Кажется, я не могу заставить работать heightForWidth.
import sys
from PySide6.QtWidgets import QApplication, QDialog, QWidget, QFrame, QGridLayout
class MyDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(600, 600)
self.my_frame = QFrame(self)
self.my_frame.setObjectName(u"my_frame")
self.my_frame.setGeometry(50, 50, 250, 250)
self.my_frame.setBaseSize(100, 100)
self.gridLayout = QGridLayout(self.my_frame)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName("gridLayout")
self.top_left = QWidget(self.my_frame)
self.top_left.setObjectName("top_left")
self.top_left.setStyleSheet("background-color: rgb(235, 10, 30)")
self.gridLayout.addWidget(self.top_left, 0, 0, 1, 1)
self.top_right = QWidget(self.my_frame)
self.top_right.setObjectName("top_right")
self.top_right.setStyleSheet("background-color: rgb(55, 122, 70)")
self.gridLayout.addWidget(self.top_right, 0, 1, 1, 1)
self.bottom_left = QWidget(self.my_frame)
self.bottom_left.setObjectName("bottom_left")
self.bottom_left.setStyleSheet("background-color: rgb(55, 122, 190)")
self.gridLayout.addWidget(self.bottom_left, 1, 0, 1, 1)
self.bottom_right = QWidget(self.my_frame)
self.bottom_right.setObjectName("bottom_right")
self.bottom_right.setStyleSheet("background-color: rgb(235, 219, 70)")
self.gridLayout.addWidget(self.bottom_right, 1, 1, 1, 1)
if __name__ == "__main__":
app = QApplication(sys.argv)
dialog = MyDialog()
dialog.show()
exit(app.exec_())
1 ответ
QLayout (например, QGridLayout) - это обработчики размера, а не визуальные элементы, поэтому нет смысла говорить, что они квадратные. С другой стороны, QGridLayout устанавливает геометрию виджетов, основываясь в основном на размере контейнера.
Таким образом, в этом случае вы должны сделать его квадратным в зависимости от размера окна, поэтому для этого вы должны переопределить метод resizeEvent и вычислить размер максимального квадрата, вписанного в окно. и, возможно, вам также следует центрировать контейнер.
class MyDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(600, 600)
qss = """
#top_left{
background-color: rgb(235, 10, 30)
}
#top_right{
background-color: rgb(55, 122, 70)
}
#bottom_left{
background-color: rgb(55, 122, 190)
}
#bottom_right{
background-color: rgb(235, 219, 70)
}
"""
self.setStyleSheet(qss)
self.my_frame = QFrame(self, objectName="my_frame")
self.gridLayout = QGridLayout(self.my_frame, objectName="gridLayout")
self.gridLayout.setSpacing(0)
self.top_left = QWidget(objectName="top_left")
self.gridLayout.addWidget(self.top_left, 0, 0, 1, 1)
self.top_right = QWidget(objectName="top_right")
self.gridLayout.addWidget(self.top_right, 0, 1, 1, 1)
self.bottom_left = QWidget(objectName="bottom_left")
self.gridLayout.addWidget(self.bottom_left, 1, 0, 1, 1)
self.bottom_right = QWidget(objectName="bottom_right")
self.gridLayout.addWidget(self.bottom_right, 1, 1, 1, 1)
def resizeEvent(self, event):
super().resizeEvent(event)
l = min(self.width(), self.height())
center = self.rect().center()
rect = QRect(0, 0, l, l)
rect.moveCenter(center)
self.my_frame.setGeometry(rect)