Как расположить виджеты так, чтобы элемент одного контейнера немного перекрывал второй контейнер?
Мой код создает две кнопки self.btn1 и self.btn2. Визуально они представляют из себя простые картинки, которые я оставлю тут:
tab1.png
tab2.png
Эти кнопки попадают в вертикальный контейнер self.box2. Далее создается контейнер box3, который обладает цветным фоном. Мне необходимо, чтобы выступ с правого края картинки tab1.png на кнопке self.btn1 перекрыл контейнер box3(основная часть обоих кнопок(большой квадрат) должна прижаться к стенкам box3), то есть нужно, чтобы кнопка self.btn1 сдвинулась по горизонтали ровно на 20px в сторону контейнера box3:
Основные части обоих кнопок должны находится ровно друг под другом, т.е., можно сказать, что подвинуться должен весь контейнер с кнопками. Конечно, можно вырезать необходимый выступ из изображения и добавить его в box3. Однако, такой способ мне не подходит. Также в контейнере box3 будут располагаться различные виджеты, т.е. выступ не должен никак влиять на расположение элементов данного контейнера. Хотелось бы, чтобы между кнопками и контейнером не появилось зазоров. Я не против другой иерархии контейнеров, главное, чтобы это визуально соответствовало картинке и масштабировалось, при изменении размеров окна. Пожалуйста, подскажите, как это сделать?
from PyQt5 import QtCore, QtGui, QtWidgets
class MyWindow(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super(MyWindow, self).__init__(*args, **kwargs)
self.resize(200, 300)
main_box = QtWidgets.QHBoxLayout(self)
btn = QtWidgets.QPushButton('Main Box')
main_box.addWidget(btn)
box1 = QtWidgets.QHBoxLayout(spacing = 0)
main_box.addLayout(box1)
self.box2 = QtWidgets.QVBoxLayout()
self.btn1 = self.make_btn('tab1.png', 70, 50)
self.box2.addWidget(self.btn1)
self.btn2 = self.make_btn('tab2.png', 50, 50)
self.box2.addWidget(self.btn2)
self.box2.addStretch(1)
label = QtWidgets.QLabel('Color Box', alignment = QtCore.Qt.AlignCenter)
box1.addLayout(self.box2)
container = QtWidgets.QWidget()
container.setStyleSheet("background-color: #7189DB;")
box1.addWidget(container)
box3 = QtWidgets.QVBoxLayout(container)
box3.addWidget(label)
def make_btn(self, picture, x, y):
btn = QtWidgets.QPushButton()
btn.setIcon(QtGui.QIcon(picture))
btn.setFixedSize(x, y)
btn.setIconSize(QtCore.QSize(x, y))
btn.setStyleSheet(qss)
return btn
qss = '''QPushButton {
border: none;
margin: 0px;
padding: 0px;
}'''
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
Ответы (1 шт):
Как вариант. Попробуйте нажимать на кнопки.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
class Container(QWidget): # +++
def __init__(self, parent):
super(Container, self).__init__(parent)
self.parent = parent
def paintEvent(self, event):
painter = QPainter(self)
painter.setBrush(QBrush(QColor(113, 137, 219)))
painter.setPen(QPen(Qt.NoPen))
painter.drawRect(0, 0, self.width(), self.height())
if self.parent._color:
self.brush = QBrush(QColor(*self.parent._color))
painter.setBrush(self.brush)
painter.drawRect(0, self.parent._height, 20, 20)
class MyWindow(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super(MyWindow, self).__init__(*args, **kwargs)
self._color = None # +++
self._height = None # +++
self.resize(200, 300)
main_box = QtWidgets.QHBoxLayout(self)
btn = QtWidgets.QPushButton('Main Box')
main_box.addWidget(btn)
box1 = QtWidgets.QHBoxLayout(spacing = 0)
main_box.addLayout(box1)
self.box2 = QtWidgets.QVBoxLayout()
# self.btn1 = self.make_btn('tab1.png', 70, 50)
self.btn1 = self.make_btn('tab1.png', 50, 50) # +++
self.box2.addWidget(self.btn1)
self.btn2 = self.make_btn('tab2.png', 50, 50)
self.box2.addWidget(self.btn2)
self.box2.addStretch(1)
label = QtWidgets.QLabel('Color Box ', alignment = QtCore.Qt.AlignCenter)
label.setMinimumWidth(100)
box1.addLayout(self.box2)
self.container = Container(self) # - QtWidgets.QWidget()
# self.container.setStyleSheet("background-color: #7189DB;") # #7189DB; # -
box1.addWidget(self.container)
box3 = QtWidgets.QVBoxLayout(self.container)
box3.addWidget(label)
def make_btn(self, picture, w, h): # w, h
btn = QtWidgets.QPushButton()
btn.setObjectName(f'{picture[:4]}') # +++
btn.clicked.connect(lambda ch, btn=btn: self.onClicked(btn)) # +++
btn.setIcon(QtGui.QIcon(picture))
btn.setFixedSize(w, h)
btn.setIconSize(QtCore.QSize(w, h))
btn.setStyleSheet(qss)
return btn
# ++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
def onClicked(self, btn):
if btn.objectName() == 'tab1':
self._color = (250, 137, 123)
self._height = 15
elif btn.objectName() == 'tab2':
self._color = (204, 171, 218)
self._height = 65
self.container.repaint()
# ++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
qss = '''QPushButton {
border: none;
margin: 0px;
padding: 0px;
}'''
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
tab1.png




