如图,绘制这样的按钮!
废话不多说,上代码!
from PySide6.QtWidgets import QApplication, QWidget
from PySide6.QtCore import Qt, QRectF, QPoint, Signal
from PySide6.QtGui import QPainter, QPainterPath, QColor, QFont
class CircleButton(QWidget):
buttonClicked = Signal(int)
def __init__(self):
super().__init__()
self.setGeometry(0, 0, 400, 400)
self.radius = 50
self.center_radius = 20
self.arc_paths = []
self.text_paths = []
self.colors = [QColor(74, 74, 74), QColor(74, 74, 74), QColor(74, 74, 74), QColor(74, 74, 74)]
self.center_color = QColor(150, 150, 150)
self.pressed_index = -1
self.initPaths()
self.show()
def initPaths(self):
rect = QRectF(-self.radius, -self.radius, self.radius * 2, self.radius * 2)
angles = [50, 140, 230, 320] #主要是这里理解一下来更改按钮的大小,理解一下arcTo(在下面几行)就能知道怎么调整了!
span = 80
for angle in angles:
path = QPainterPath()
path.moveTo(0, 0)
path.arcTo(rect, angle, span)
path.closeSubpath()
inner_circle = QPainterPath()
inner_circle.addEllipse(QPoint(0, 0), self.center_radius, self.center_radius)
path -= inner_circle
self.arc_paths.append(path)
center_path = QPainterPath()
center_path.addEllipse(QPoint(0, 0), self.center_radius-10, self.center_radius-10)
self.arc_paths.append(center_path)
# Define patterns for each button
patterns = [
QPainterPath(), # Up arrow
QPainterPath(), # Left arrow
QPainterPath(), # Down arrow
QPainterPath(), # Right arrow
QPainterPath() # Center circle
]
# Create up arrow pattern (centered)
patterns[0].moveTo(-8, -5)
patterns[0].lineTo(0, -15)
patterns[0].lineTo(8, -5)
patterns[0].closeSubpath()
# Create left arrow pattern (centered)
patterns[1].moveTo(-5, -8)
patterns[1].lineTo(-15, 0)
patterns[1].lineTo(-5, 8)
patterns[1].closeSubpath()
# Create down arrow pattern (centered)
patterns[2].moveTo(-8, 5)
patterns[2].lineTo(0, 15)
patterns[2].lineTo(8, 5)
patterns[2].closeSubpath()
# Create right arrow pattern (centered)
patterns[3].moveTo(5, -8)
patterns[3].lineTo(15, 0)
patterns[3].lineTo(5, 8)
patterns[3].closeSubpath()
# Create center circle pattern
patterns[4].addEllipse(QPoint(0, 0), 8, 8)
# Position offsets for each pattern (centered within their respective sections)
positions = [
QPoint(0, -self.radius/2), # Up
QPoint(-self.radius/2, 0), # Left
QPoint(0, self.radius/2), # Down
QPoint(self.radius/2, 0), # Right
QPoint(0, 0) # Center
]
# Add patterns to text_paths
for path, pos in zip(patterns, positions):
pattern_path = QPainterPath()
pattern_path.addPath(path)
pattern_path.translate(pos)
self.text_paths.append(pattern_path)
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.translate(self.width() / 2, self.height() / 2)
for i, path in enumerate(self.arc_paths):
color = self.colors[i] if i < 4 else self.center_color
painter.setBrush(color)
painter.setPen(Qt.NoPen)
painter.drawPath(path)
if i == self.pressed_index:
painter.setBrush(QColor(255, 255, 255, 100))
painter.drawPath(path)
painter.setBrush(Qt.black)
painter.drawPath(self.text_paths[i])
def mousePressEvent(self, event):
pos = event.position() - QPoint(self.width() / 2, self.height() / 2)
for i, path in enumerate(self.arc_paths):
if path.contains(pos):
self.pressed_index = i
self.buttonClicked.emit(i)
self.update()
break
def mouseReleaseEvent(self, event):
self.pressed_index = -1
self.update()
if __name__ == '__main__':
app = QApplication([])
widget = CircleButton()
widget.buttonClicked.connect(lambda idx: print(f"Button {idx} clicked"))
app.exec()