我正在嘗試創建一個自定義復選框。我正在使用paintEvent函式來創建我的特殊復選框。它的設計:

Qt 上的結果:

首先,要加圓角,線條的交界處要過渡更平滑。我需要一個更專業的解決方案。這看起來很漂亮。謝謝!代碼:
import sys, os, time
from PySide6 import QtCore, QtWidgets, QtGui
from PySide6.QtWidgets import *
from PySide6.QtCore import *
from PySide6.QtGui import *
class ECheckBoxData(object):
Radius = 10
AnimationTime = 600 # ms
FontSize, FontSpacing = 16, 0
Color = {
"CORNER": QColor(239, 239, 239),
"BASE_BACKGROUND": QColor(255, 125, 51),
"BASE_FOREGROUND": QColor(255, 152, 91),
"BASE_HOVER_BACKGROUND" :QColor(255, 152, 91),
"BASE_HOVER_FOREGROUND": QColor(247, 247, 250),
}
TextElide = Qt.ElideMiddle
CheckWidth, CheckHeight = 128, 128
class ECheckBox(QCheckBox):
CheckBoxData = ECheckBoxData()
def __init__(self, CheckBoxData=ECheckBoxData()):
super(ECheckBox, self).__init__(None)
self.CheckBoxData = CheckBoxData
self.myfont = QFont("Times New Roman", 16, weight=QFont.Bold)
self.myfont.setWordSpacing(self.CheckBoxData.FontSpacing)
self.myfont.setStyleHint(QFont.Monospace)
self.myfontMetrics = QFontMetrics(self.myfont)
# font.setStyleHint(QFont.Times, QFont.PreferAntialias)
self.setFont(self.myfont)
self.setFixedHeight(self.CheckBoxData.CheckHeight 2)
self.setMinimumWidth(self.CheckBoxData.CheckWidth 8)
def paintEvent(self, event: QPaintEvent):
pt = QPainter(self)
pt.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing )
border = QPainterPath()
pt.setBrush(self.CheckBoxData.Color["BASE_BACKGROUND"])
pt.setPen(QPen(self.CheckBoxData.Color["CORNER"],5))
border.addRoundedRect(QRectF(2,2,self.CheckBoxData.CheckWidth-2, self.CheckBoxData.CheckHeight-2),self.CheckBoxData.Radius, self.CheckBoxData.Radius)
pt.drawPath(border)
pt.setClipPath(border)
pt.setPen(QPen(Qt.white,self.CheckBoxData.CheckWidth/10))
pt.setBrush(Qt.white)
path2 = QPainterPath()
arrow_width, arrow_height = self.width()/4, self.height()/ (66/8)
center_width, center_height = int(self.width()/2), int(self.height()/2)
#path2.moveTo((self.width() - arrow_width * 2) / 2, (center_height 2))
#path2.lineTo(QPoint((self.width() - arrow_width) / 2 2, (center_height) arrow_height 1))
#path2.lineTo(QPoint((self.width()-arrow_width), (center_height)-arrow_height))
path2.addPolygon(QPolygonF([
QPoint((self.width()-arrow_width*2)/2, (center_height 2)), QPoint((self.width()-arrow_width)/2 2, (center_height) arrow_height 1)
]))
path2.addPolygon(QPolygonF([QPoint((self.width()-arrow_width)/2 2, (center_height) arrow_height 1), QPoint((self.width()-arrow_width-12), (center_height)-arrow_height)]))
pt.drawPath(path2)
if __name__ == "__main__":
app = QApplication(sys.argv)
wind = QMainWindow()
wind.setStyleSheet("QMainWindow{background-color:rgb(247,247,250)}")
wind.resize(221, 150)
wid = QWidget()
lay = QHBoxLayout(wid)
lay.setAlignment(Qt.AlignCenter)
Data = ECheckBoxData()
e = ECheckBox(Data)
e.setChecked(True)
lay.addWidget(e)
wind.setCentralWidget(wid)
wind.show()
sys.exit(app.exec())
uj5u.com熱心網友回復:
為了創建平滑和彎曲的輪廓,您需要正確設定 QPen帽和連接樣式。
使用多邊形繪制輪廓顯然不是一個有效的解決方案,因為該輪廓將用筆繪制,但您需要的是一條用粗筆繪制的路徑以及首選的帽和連接樣式。
此外,為了能夠繪制不同尺寸的好圖示,您不應依賴固定尺寸(即使正確計算),而應使用當前尺寸作為參考。
def paintEvent(self, event: QPaintEvent):
pt = QPainter(self)
pt.setRenderHints(QPainter.Antialiasing | QPainter.TextAntialiasing)
size = min(self.width(), self.height())
border = max(1, size / 32)
rect = QRectF(0, 0, size - border, size - border)
# move the square to the *exact* center using a QRectF based on the
# current widget; note: it is very important that you get the center
# using a QRectF, because the center of QRect is always in integer
# values, and will almost always be imprecise at small sizes
rect.moveCenter(QRectF(self.rect()).center())
borderPath = QPainterPath()
# with RelativeSize we can specify the radius as 30% of half the size
borderPath.addRoundedRect(rect, 30, 30, Qt.RelativeSize)
pt.setBrush(self.CheckBoxData.Color["BASE_BACKGROUND"])
pt.setPen(QPen(self.CheckBoxData.Color["CORNER"], border * 2.5))
pt.drawPath(borderPath)
pt.setPen(QPen(Qt.white, size * .125,
cap=Qt.RoundCap, join=Qt.RoundJoin))
arrow_path = QPainterPath()
arrow_path.moveTo(size * .25, size * .5)
arrow_path.lineTo(size * .40, size * .65)
arrow_path.lineTo(size * .7, size * .325)
pt.drawPath(arrow_path.translated(rect.topLeft()))
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/451443.html
