python - Qt 带有圆角的消息

标签 python qt pyqt5 qt5 pyside2

我正在尝试创建一个小部件,例如这张图片底部的消息框:

img

它应该覆盖主小部件。我有两种方法可以做到这一点:

  • 带有 QFrame 和圆角
  • 戴着口罩

但是他们每个人都有一个问题:

  • QFrame 方法似乎是一个更好的主意,但背景不透明。这意味着即使边框有半径,背景仍然使其成为矩形。从图中可以看出一些。不幸的是,this似乎不起作用。与 self.setStyleSheet("background:transparent") 相同。

img

  • 蒙版看起来非常像素化,这不是预期的行为,因为使用的蒙版只能是一个简单的 QRegion。这些没有松鼠,这将是理想的。

img

代码如下:

class Message(QFrame):
    """
    A temporary message to show information in the GUI.
    """

    def __init__(self, msg: str, *args, destroy_time: int = None):
        super().__init__(*args)

        # Main layout
        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        # The label
        label = QLabel(msg)
        label.setFont(Fonts.text)
        label.setStyleSheet(f"color: {Colors.fg};"
                            "padding: 20px;")
        self.layout.addWidget(label)
        self.setStyleSheet(f"background-color: {Colors.bg};"
                           "border-radius: 30px;")

        #  region = QRegion(self.x(), self.y(), self.sizeHint().width(),
                         #  self.sizeHint().height(), QRegion.Ellipse)
        #  self.setMask(region)

        self.adjustSize()

S. Nick 的编辑:仅当消息小部件是应用程序中唯一的小部件时,您的解决方案才有效。预期用途是这样的:

class MainWindow(QWidget):
    def __init__(self, player: QWidget):
        super().__init__()

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(player)

        msg = Message("I can't make this work", self)

其中 player 是主小部件,消息出现时会覆盖它。想象它是一张图像,上面覆盖着消息。抱歉没有正确解释自己。

最佳答案

尝试一下:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class Message(QWidget):   #(QFrame): #
    def __init__(self, msg: str, *args, destroy_time: int = None):
        super().__init__(*args)

        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint) # <---
        self.setAttribute(Qt.WA_TranslucentBackground)                   # <---

        Colors_fg = "#fa0"
        Colors_bg = "rgba( 155, 155, 155, 150)"                          # <---

        # Main layout
        self.layout = QVBoxLayout(self)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        # The label
        label = QLabel(msg, alignment=Qt.AlignCenter)
        label.setFont(QFont("Times", 17, QFont.Bold, italic=True))       #(Fonts.text)
        label.setStyleSheet(f"color: {Colors_fg};"
                             "padding: 0px;")
        self.layout.addWidget(label)

# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv        
        self.setStyleSheet(f"background-color: {Colors_bg};"  
                            "min-height: 70px;"
                            "max-height: 70px;"
                            "width: 200px;"
                            "border-radius: 30px;"
                           )
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        self.adjustSize()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Message("Hello \nWorld")
    w.resize(400, 200)
    w.show()
    sys.exit(app.exec_())

enter image description here


更新

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class Message(QDialog):      #(QFrame):
    def __init__(self, msg: str, *args, destroy_time: int = None):
        super().__init__(*args)
        self.setWindowFlags(self.windowFlags() | 
                            Qt.FramelessWindowHint |
                            Qt.WindowStaysOnTopHint) 
        self.setAttribute(Qt.WA_TranslucentBackground)                   

        self.widget = QWidget(self)
        self.widget.setObjectName('Custom_Widget')
        layout = QVBoxLayout(self)
        layout.addWidget(self.widget)

        self.layout = QGridLayout(self.widget)
        self.layout.addItem(QSpacerItem(
            40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum), 0, 0)
        self.layout.addWidget(QPushButton('r', self, 
                                          clicked=self.accept, 
                                          objectName='closeButton'), 0, 1)
        # The label
        label = QLabel(msg)
        label.setFont(QFont("Times", 17, QFont.Bold, italic=True))         #((Fonts.text)
        self.layout.addWidget(label, 2, 0, 5, 2, alignment=Qt.AlignCenter)                           
        self.adjustSize()

    def mousePressEvent(self, event):
        self.old_Pos    = event.globalPos()
        self.old_width  = self.width()
        self.old_height = self.height()

    def mouseMoveEvent(self, event):
        if (event.buttons() == Qt.LeftButton): 
            delta = QPoint (event.globalPos() - self.old_Pos)
            if (self.old_Pos.x() > self.x() + self.old_width - 20) or \
               (self.old_Pos.y() > self.y() + self.old_height - 20):
                w = self.old_width+delta.x()  if self.old_width+delta.x()  > 500 else 500
                h = self.old_height+delta.y() if self.old_height+delta.y() > 400 else 400
                self.setFixedSize(w, h)
            else:
                self.move(self.x() + delta.x(), self.y() + delta.y())
                self.old_Pos = event.globalPos()


class MainWindow(QWidget):
    def __init__(self, player: QWidget):
        super().__init__()

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(player)

        self.msg = Message("I can't make this work")#, self)        
        self.msg.show()


Stylesheet = """
#Custom_Widget {
    background: rgba( 155, 155, 155, 150);
    border-radius: 20px;
    border: 2px solid #ff2025;                   
}
#closeButton {
    min-width: 36px;
    min-height: 36px;
    font-family: "Webdings";
    qproperty-text: "r";
    border-radius: 10px;
}
#closeButton:hover {
    color: #ccc;
    background: red;
}
"""

if __name__ == '__main__':
    app = QApplication(sys.argv)

    app.setStyleSheet(Stylesheet)

    w = MainWindow(QPushButton("player"))
    w.resize(400, 200)
    w.show()
    sys.exit(app.exec_())

enter image description here


更新2

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class Message(QFrame):      # QDialog
    def __init__(self, msg: str, *args, destroy_time: int = None):
        super().__init__(*args)
#        self.setWindowFlags(self.windowFlags() | 
#                            Qt.FramelessWindowHint #|Qt.WindowStaysOnTopHint) 
        self.setAttribute(Qt.WA_TranslucentBackground)                   

        self.widget = QWidget(self)
        self.widget.setObjectName('Custom_Widget')
        layout = QVBoxLayout(self)
        layout.addWidget(self.widget)

        self.layout = QGridLayout(self.widget)
        self.layout.addItem(QSpacerItem(
            40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum), 0, 0)
        self.layout.addWidget(QPushButton('r', self, 
#                                          clicked=self.accept, 
                                          clicked=self.close, 
                                          objectName='closeButton'), 0, 1)
        # The label
        label = QLabel(msg)
        label.setFont(QFont("Times", 15, QFont.Bold, italic=True))         #((Fonts.text)
        self.layout.addWidget(label, 2, 0, 5, 2, alignment=Qt.AlignCenter)                           
        self.adjustSize()


class MainWindow(QWidget):
    def __init__(self, player: QWidget):
        super().__init__()

        layout = QHBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)
        layout.addWidget(player)
        player.clicked.connect(self._msg)

    def _msg(self):
        self.msg = Message("I can't make this work\nself.msg.setGeometry(10, 10, 480, 150)", self)        
        self.msg.setGeometry(10, 10, 480, 150)
        self.msg.show()


Stylesheet = """
#Custom_Widget {
    background: rgba( 155, 155, 155, 150);
    border-radius: 20px;
    border: 2px solid #ff2025;                   
}
#closeButton {
    min-width: 36px;
    min-height: 36px;
    font-family: "Webdings";
    qproperty-text: "r";
    border-radius: 10px;
}
#closeButton:hover {
    color: #ccc;
    background: red;
}
"""

if __name__ == '__main__':
    app = QApplication(sys.argv)

    app.setStyleSheet(Stylesheet)

    w = MainWindow(QPushButton("player"))
    w.resize(500, 400)
    w.show()
    sys.exit(app.exec_())

enter image description here

关于python - Qt 带有圆角的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58626216/

相关文章:

python - math.sqrt 结果 TypeError :'float' 对象无法解释为整数

python - 为什么在 Python 中获取 postgreSQL 表比在 R 中慢得多?

python - CSV 阅读器不读取整个文件

c++ - 黑莓 10 : GNU STL

python - PyQt5 keyPressEvent 的工作原理

python - Pytest:如何通过输入调用测试单独的函数?

Qt:QGuiApplication 和 QQmlApplicationEngine 如何交互?

python - 应用程序未在 macOS Big Sur 11.0.1 上弹出

python - 更改 QTreeView 中的某些数据

c++ - Qt 中的 2D 游戏 : Initializing monsters and passing dynamically allocated array as a pointer parameter