QPushButton圆角渐变边框与QSS

3
我正在尝试使用QSS在Qt中进行一些“复杂”的按钮样式设计,但我遇到了一个无法解决的问题。
我想要做一个渐变圆角边框,例如从左侧的蓝色到右侧的红色:
所需结果
因此,这是应用于QPushButton的样式表:
background:
    white;
border-radius:
    30px;
border-style:
    solid;
border-width:
    10px;
border-color: 
    qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 blue, stop: 1 red)
    red
    qlineargradient(x1:0, y1:0, x2:1, y2:0, stop: 0 blue, stop: 1 red)
    blue;

以下是结果。

相当丑陋,对吧?


当你删除半径时,它可以正常工作。似乎渐变是针对边框的半径部分单独计算的,而这个半径部分对于每个边框来说都是角落的一半。 - ymoreau
这是关键,我需要半径 ;) - aRaMinet
3个回答

3
这个问题已被报告给Qt作为错误,并且没有迹象表明他们会修复它:https://bugreports.qt.io/browse/QTBUG-2221 我通过在paint.net(您可以使用任何图像创建程序)上创建一个与所需边框完全相同的.png图像来解决了它。我将背景设置为透明,并确保图像的边框是我想要的QPushButton的边框。然后,我将.png文件设置为资源,并在QPushButton样式表中输入了这个:
border: none;
border-image: url(:/icons/images/blue-red-gradient.png);
background-color: rgb(255, 255, 255);
border-radius: 15px;

以下是我的QMainWindow上的最终结果: enter image description here 还有一件事情可以做的是,子类化QPushButton并覆盖它的绘图事件。在那里绘制边框,并将所有的QPushButtons提升为这个新类。虽然这会更麻烦一些,但我个人更喜欢第一个解决方案。

0

我搜索了一下,发现有两种方法,但第二种方法使用了border-image,不兼容border-radius,所以你需要处理:before和:after。

这是Camilo Martin的答案链接:

查看答案这里


很遗憾,Qt样式表中无法使用":after"关键字。我可以有效地创建一个小部件,将矩形和按钮堆叠在一起,但这样做会失去样式表的灵活性。 - aRaMinet

0
这可能对你有帮助,虽然有点晚但可能对其他人有帮助。
import sys

from PyQt5.QtCore import pyqtSignal
import sys
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, 
QWidget, QFrame

class StyledButton(QFrame):
    clicked = pyqtSignal()

    def __init__(self, parent=None, size_=(150, 50), border_=3, 
radius_=10):
    super().__init__(parent)
    self.size_ = size_
    self.border_ = border_
    self.radius_ = radius_
    self.init_ui()

def init_ui(self):
    if self.size_ is not None:
        self.setFixedSize(self.size_[0] + (self.border_ * 2), self.size_[1] + (self.border_ * 2))
    self.setFrameStyle(QFrame.Box | QFrame.Plain)
    self.setStyleSheet(f"border-radius: {self.radius_}px;")  # Set rounded corners

    gradient_style = f"border: none; border-radius: {self.radius_ * 0.5}px; background: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 1, stop: 0 #f00, stop: 0.25 #f0f, stop: 0.5 #f00, stop: 0.75 #00f, stop: 1 #0f0);"
    self.setStyleSheet(gradient_style)

    self.button = QPushButton('Button')
    self.button.setFixedSize(self.size_[0], self.size_[1])
    self.button.setStyleSheet('background-color: black; color: white;')

    self.layout = QVBoxLayout(self)
    self.layout.setContentsMargins(self.border_, self.border_, self.border_, self.border_)

    self.layout.addWidget(self.button)

    # Connect QPushButton's clicked signal to emit the custom signal from StyledButton
    self.button.clicked.connect(self.emit_custom_signal)

def emit_custom_signal(self):
    self.clicked.emit()

def fun():
    print("Button is clicked")

def main():
    app = QApplication(sys.argv)

    layout = QVBoxLayout()
    combined_widget = StyledButton()
    combined_widget1 = StyledButton()
    combined_widget1.button.setStyleSheet('background-color: green; color: red;')
    combined_widget2 = StyledButton()
    combined_widget3 = StyledButton()

    combined_widget.clicked.connect(fun)  # Connect the custom signal to the function
    layout.addWidget(combined_widget)
    layout.addWidget(combined_widget1)
    layout.addWidget(combined_widget2)
    layout.addWidget(combined_widget3)

    window = QWidget()
    window.setLayout(layout)
    window.show()

    sys.exit(app.exec_())

 if __name__ == "__main__":
    main()

带有渐变的圆形按钮

带有渐变的圆形按钮


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接