Делать то, что вы хотите, с помощью базовых c виджетов, предоставляемых Qt, возможно, но есть некоторые недостатки и соображения, о которых следует помнить.
Я полагаю, что три изображения, которые вы хотите показать, это " Выровняйте фигуры справа, и если это так, вы не можете использовать макет, потому что их геометрия перекрывается: для виджета этого типа и вида вы должны «встроить» дочерние виджеты, не назначая их макету.
Затем, если вы хотите, чтобы эти полукруглые стрелки реагировали как кнопки, очевидно, что вы не можете использовать basi c QPushButtons, поскольку они имеют прямоугольную форму angular. Решением может быть создание подкласса, переопределение paintEvent (для предоставления пользовательского рисунка кнопки с использованием вашего изображения), а затем использование изображения для создания маски для виджета, чтобы события щелчка происходили только в пределах его границ.
Это базовый c пример того, что это может быть:
class MyButton(QtWidgets.QPushButton):
def __init__(self, image, parent):
super().__init__(parent)
self.image = QtGui.QPixmap(image)
self.setFixedSize(self.image.size())
self.setMask(self.image.createHeuristicMask())
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.drawPixmap(QtCore.QPoint(), self.image)
class MyWidget(QtWidgets.QWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setFixedSize(110, 140)
self.upButton = MyButton('uparrow.png', self)
self.downButton = MyButton('downarrow.png', self)
self.downButton.move(0, self.height() - self.downButton.height())
self.rtcA = QtWidgets.QLabel(self)
self.rtcA.setPixmap(QtGui.QPixmap('rtcA.png'))
self.rtcB = QtWidgets.QLabel(self)
self.rtcB.setPixmap(QtGui.QPixmap('rtcB.png'))
self.rtcC = QtWidgets.QLabel(self)
self.rtcC.setPixmap(QtGui.QPixmap('rtcC.png'))
for label in self.rtcA, self.rtcB, self.rtcC:
label.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents)
self.upButton.clicked.connect(self.up)
self.downButton.clicked.connect(self.down)
p = self.palette()
p.setColor(p.Window, QtGui.QColor(57, 57, 57))
self.setPalette(p)
def up(self):
print('going up')
def down(self):
print('going down')
А вот как это выглядит:
Как видите, я не использовал никакой разметки: вы можете добавить дочерние элементы в виджет "контейнер", просто добавив этот виджет в качестве аргумента parent
; это заставляет этих детей появляться внутри контейнера, и их можно свободно перемещать в пределах родительских границ.
Некоторые небольшие заметки.
Для трех индикаторов я использовал изображения, которые уже "переводят" msgstr "фактическое содержимое изображения (это означает, что оно размещено в верхнем левом углу виджета). Это делается для того, чтобы они были правильно выровнены и чтобы избежать непрерывных проб и ошибок, чтобы получить позицию на виджете; например, третье изображение на самом деле выглядит так:
Чтобы эта работа работала, как и ожидалось, мне пришлось сделать эти виджеты «прозрачными для событий мыши» : поскольку они добавляются после кнопок, они будут над ними, и кнопки не получат никакого события мыши, потому что метки будут в пути. Другая возможность - добавить кнопки после надписей или, в противном случае, использовать raise_()
или lower()
:
self.upButton.raise_()
self.downButton.raise_()
# or, alternatively
for label in self.rtcA, self.rtcB, self.rtcC:
label.lower()
. В качестве дополнительной возможности вы можете создавать «маскирующие изображения». «для каждой метки (с solid -нон-альфа-фоном вокруг границ каждого раздела) и используйте setMask(QtGui.QPixmap('rtcA_mask.png').createHeuristicMask())
аналогично тому, что я сделал для кнопок. Преимущество этого подхода состоит в том, что события мыши могут быть правильно получены от этих меток, если они вам когда-либо понадобятся.