Как задать ширину контейнера PyQt5?(Python3)
У меня есть код, который я оставлю ниже.
Класс Label принимает путь к изображению и закругляет его края. Из-за некоторых обстоятельств буду использовать его экземпляры вместо кнопок.
В классе MyWindow я создаю два QGridLayout'а - box1 и box3 и один QVBoxLayout - box2.
- В
box2добавляю кнопкуbutton. box3наполняю двумя виджетамиQLabel, которые получаю из классаLabel.box2иbox3помещаю вbox1.
Первый виджет QLabel label1 использую вместо кнопки - привязываю к нему метод click, который очищает контейнер box3 и создает внутри него новую кнопку.
Если начать увеличивать размер окна, то размер QVBoxLayout то же начинает увеличиваться. Но, почему-то, если нажать на label1, вызвав метод click, который очищает box3, содержимое контейнера box2 прилипнет к правой стенке окна. Хотел бы понять, почему это происходит, но это не самое главное, что я хотел спросить.
Я хочу зафиксировать ширину контейнера box2(высоту мне нужно оставить изменяемой при масштабировании окна), чтобы было понятнее, нарисовал схему:
Вот код:
from PyQt5 import QtCore, QtWidgets, QtGui
class Label(QtWidgets.QLabel):
clicked = QtCore.pyqtSignal()
def __init__(self, picture, *args, **kwargs):
super(Label, self).__init__(*args, **kwargs)
self.setMaximumSize(140, 140)
self.setMinimumSize(140, 140)
self.radius = 10
self.target = QtGui.QPixmap(self.size())
self.target.fill(QtCore.Qt.transparent)
p = QtGui.QPixmap(picture).scaled(140, 140, QtCore.Qt.KeepAspectRatioByExpanding, QtCore.Qt.SmoothTransformation)
painter = QtGui.QPainter(self.target)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
painter.setRenderHint(QtGui.QPainter.HighQualityAntialiasing, True)
painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform, True)
path = QtGui.QPainterPath()
path.addRoundedRect(0, 0, self.width(), self.height(), self.radius, self.radius)
painter.setClipPath(path)
painter.drawPixmap(0, 0, p)
self.setPixmap(self.target)
def mouseReleaseEvent(self, event):
self.clicked.emit()
class MyWindow(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.box1 = QtWidgets.QGridLayout()
self.box2 = QtWidgets.QVBoxLayout()
self.button = QtWidgets.QPushButton('Button')
self.button.setFixedSize(60, 60)
self.box2.addWidget(self.button)
self.box1.addLayout(self.box2, 0, 1)
self.new_button = QtWidgets.QPushButton('New Button')
self.box3 = QtWidgets.QGridLayout()
self.box3.setSpacing(20)
self.label1 = Label('picture1.png')
self.label2 = Label('picture1.png')
self.label1.clicked.connect(self.click)
self.box3.addWidget(self.label1, 0, 0)
self.box3.addWidget(self.label2, 0, 1)
self.box1.addLayout(self.box3, 0, 0)
self.setLayout(self.box1)
def click(self):
for row in range(self.box3.rowCount()):
for col in range(self.box3.columnCount()):
w = self.box3.itemAtPosition(row, col).widget()
w.deleteLater()
self.box3.addWidget(self.new_button, 0, 0, 1, 1, QtCore.Qt.AlignCenter)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.setWindowTitle(' ')
window.show()
sys.exit(app.exec_())
Пожалуйста, подскажите, как мне это сделать?
Ответы (1 шт):
я конечно извиняюсь, но я расставил строки в классе MyWindow как мне удобнее и понятнее. Т.е. сразу виджеты, а потом Layout'ы.
Я добавил setStyleSheet во все виджеты, чтобы вы видели, где они расположены и сколько места занимают.
Уберете их потом.
По сути:
- прибил :)
self.buttonк правой сторонеalignment=QtCore.Qt.AlignRight - добавил
AlignCenterself.box1.addLayout(self.box3, 0, 0, 1, 1, QtCore.Qt.AlignCenter) - добавил
self.box1.setColumnStretch(0, 1)QGridLayout::setColumnStretch(int column, int stretch). Читать здесь https://doc.qt.io/qt-5/qgridlayout.html#setColumnStretch
from PyQt5 import QtCore, QtWidgets, QtGui
class Label(QtWidgets.QLabel):
clicked = QtCore.pyqtSignal()
def __init__(self, picture, *args, **kwargs):
super(Label, self).__init__(*args, **kwargs)
self.setMaximumSize(140, 140)
self.setMinimumSize(140, 140)
self.radius = 10
self.target = QtGui.QPixmap(self.size())
self.target.fill(QtCore.Qt.transparent)
p = QtGui.QPixmap(picture).scaled(140, 140, QtCore.Qt.KeepAspectRatioByExpanding, QtCore.Qt.SmoothTransformation)
painter = QtGui.QPainter(self.target)
painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
painter.setRenderHint(QtGui.QPainter.HighQualityAntialiasing, True)
painter.setRenderHint(QtGui.QPainter.SmoothPixmapTransform, True)
path = QtGui.QPainterPath()
path.addRoundedRect(0, 0, self.width(), self.height(), self.radius, self.radius)
painter.setClipPath(path)
painter.drawPixmap(0, 0, p)
self.setPixmap(self.target)
def mouseReleaseEvent(self, event):
self.clicked.emit()
class MyWindow(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.button = QtWidgets.QPushButton('Button')
self.button.setFixedSize(60, 60)
self.button.setStyleSheet('background-color: #0f0;')
self.label1 = Label('head3.png')
self.label1.setStyleSheet('background-color: #0ff;')
self.label1.clicked.connect(self.click)
self.label2 = Label('Ok.png')
self.label2.setStyleSheet('background-color: #8ff;')
self.new_button = QtWidgets.QPushButton('New Button')
self.new_button.setStyleSheet('background-color: #ff0;')
self.box2 = QtWidgets.QVBoxLayout()
self.box2.addWidget(self.button, alignment=QtCore.Qt.AlignRight) # +++
self.box3 = QtWidgets.QGridLayout()
self.box3.setSpacing(20)
self.box3.addWidget(self.label1, 0, 0)
self.box3.addWidget(self.label2, 0, 1)
self.box1 = QtWidgets.QGridLayout(self)
self.box1.addLayout(self.box3, 0, 0, 1, 1, QtCore.Qt.AlignCenter) # +++
self.box1.setColumnStretch(0, 1) # +++
self.box1.addLayout(self.box2, 0, 1)
def click(self):
for row in range(self.box3.rowCount()):
for col in range(self.box3.columnCount()):
w = self.box3.itemAtPosition(row, col).widget()
w.deleteLater()
self.box3.addWidget(self.new_button, 0, 0, 1, 1, QtCore.Qt.AlignCenter)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = MyWindow()
window.setWindowTitle(' ')
window.show()
sys.exit(app.exec_())


