如何在彼此之上添加 pyqt5 按钮?

我正在尝试在 pyqt 中创建一个基本的 25 键键盘,我已经布置了 15 个白键,但正在努力添加剩余的 10 个黑键,


这就是我制作钥匙的方式


from PyQt5.QtWidgets import QApplication, QPushButton

app = QApplication([])


top_win = QWidget() 

set_color(top_win, Qt.cyan)

top_win.setAutoFillBackground(True)

top_win.show() 

top_win.resize(1920,1080)

top_win.setWindowTitle("Synth-01") 

top_vlayout = QVBoxLayout()

top_win.setLayout(top_vlayout)


keyboard = QWidget()

keyboard.setMaximumWidth(1410)

top_vlayout.addWidget(keyboard)


keyboard_layout = QHBoxLayout()

keyboard.setAutoFillBackground(True)

keyboard.setLayout(keyboard_layout)


for i in range(15):

    name = "key_" + str(i)

    name = QPushButton()

    name.setMaximumWidth(94)

    name.setMaximumHeight(349)

    keyboard_layout.addWidget(name)

http://img2.mukewang.com/61bbf43d0001e81b15140367.jpg

我现在想像这样在中间添加黑键

http://img1.mukewang.com/61bbf44d0001266f04720156.jpg

UYOU
浏览 157回答 1
1回答

慕运维8079593

在这种情况下,最好将 QGraphicsScene 与 QGraphicsItem 一起使用,对于这种情况,我将使用 svg:from PyQt5 import QtCore, QtGui, QtWidgets, QtSvg class PianoKey(QtWidgets.QGraphicsRectItem):    def __init__(self, black=False, rect = QtCore.QRectF(), parent=None):        super(PianoKey, self).__init__(rect, parent)        self.m_pressed = False        self.m_selectedBrush = QtGui.QBrush()        self.m_brush = QtGui.QBrush(QtCore.Qt.black) if black else QtGui.QBrush(QtCore.Qt.white)         self.m_black = black    def setPressedBrush(self, brush):        self.m_selectedBrush = brush    def paint(self, painter, option, widget):        rendered = QtSvg.QSvgRenderer("key.svg")        black_pen = QtGui.QPen(QtCore.Qt.black, 1)        gray_pen = QtGui.QPen(QtGui.QBrush(QtCore.Qt.gray), 1,             QtCore.Qt.SolidLine, QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)        if self.m_pressed:            if self.m_selectedBrush.style() != QtCore.Qt.NoBrush:                painter.setBrush(self.m_selectedBrush)            else:                painter.setBrush(QtWidgets.QApplication.palette().highlight())        else:             painter.setBrush(self.m_brush);        painter.setPen(black_pen)        painter.drawRoundedRect(self.rect(), 15, 15, QtCore.Qt.RelativeSize)        if self.m_black:            rendered.render(painter, self.rect())        else:            points = [                QtCore.QPointF(self.rect().left()+1.5, self.rect().bottom()-1),                QtCore.QPointF(self.rect().right()-1, self.rect().bottom()-1),                QtCore.QPointF(self.rect().right()-1, self.rect().top()+1)            ]            painter.setPen(gray_pen)            painter.drawPolyline(QtGui.QPolygonF(points))    def mousePressEvent(self, event):        self.m_pressed = True        self.update()        super(PianoKey, self).mousePressEvent(event)        event.accept()    def mouseReleaseEvent(self, event):        self.m_pressed = False        self.update()        super(PianoKey, self).mouseReleaseEvent(event)KEYWIDTH, KEYHEIGHT = 18, 72class PianoKeyBoard(QtWidgets.QGraphicsView):    def __init__(self, num_octaves=2,  parent=None):        super(PianoKeyBoard, self).__init__(parent)        self.initialize()        self.m_numOctaves = num_octaves        scene = QtWidgets.QGraphicsScene(QtCore.QRectF(0, 0, KEYWIDTH * self.m_numOctaves * 7, KEYHEIGHT), self)        self.setScene(scene)        numkeys = self.m_numOctaves * 12        for i in range(numkeys):            octave = i//12*7            j = i % 12            if j >= 5: j += 1            if j % 2 == 0:                x = (octave + j/2)*KEYWIDTH                key = PianoKey(rect=QtCore.QRectF(x, 0, KEYWIDTH, KEYHEIGHT), black=False)            else:                x = (octave + j//2) * KEYWIDTH  + KEYWIDTH * 6//10 + 1                key = PianoKey(rect=QtCore.QRectF(x, 0, KEYWIDTH * 8//10 - 1, KEYHEIGHT * 6//10 ), black=True)                key.setZValue(1)            key.setPressedBrush(QtWidgets.QApplication.palette().highlight())            self.scene().addItem(key)    def initialize(self):        self.setAttribute(QtCore.Qt.WA_InputMethodEnabled, False)        self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)        self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)        self.setCacheMode(QtWidgets.QGraphicsView.CacheBackground)        self.setViewportUpdateMode(QtWidgets.QGraphicsView.MinimalViewportUpdate)        self.setRenderHints(QtGui.QPainter.Antialiasing|            QtGui.QPainter.TextAntialiasing |             QtGui.QPainter.SmoothPixmapTransform)        self.setOptimizationFlag(QtWidgets.QGraphicsView.DontClipPainter, True)        self.setOptimizationFlag(QtWidgets.QGraphicsView.DontSavePainterState, True)        self.setOptimizationFlag(QtWidgets.QGraphicsView.DontAdjustForAntialiasing, True)        self.setBackgroundBrush(QtWidgets.QApplication.palette().base())    def resizeEvent(self, event):        super(PianoKeyBoard, self).resizeEvent(event)        self.fitInView(self.scene().sceneRect(), QtCore.Qt.KeepAspectRatio)    def sizeHint(self):        return self.mapFromScene(self.sceneRect()).boundingRect().size()if __name__ == '__main__':    import sys    app = QtWidgets.QApplication(sys.argv)    app.setStyle('fusion')    w = QtWidgets.QWidget()    lay = QtWidgets.QVBoxLayout(w)    lay.addWidget(QtWidgets.QLabel("Piano Keyboard", alignment=QtCore.Qt.AlignCenter))    lay.addWidget(PianoKeyBoard())    w.resize(640, 480)    w.show()    sys.exit(app.exec_())完整的代码 + key.svg 可以在这个链接上找到
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python