【问题标题】:Overflow Widgets in that rounded corners QFrame圆角 QFrame 中的溢出小部件
【发布时间】:2020-11-20 13:18:32
【问题描述】:

当我像这样设置 QFrame 的样式表时,我遇到了 QFrame 的问题;

frame = QFrame(self.window)
frame.setObjectName('Custom_Widget')
frame.setStyleSheet("""
   #Custom_Widget {
     background: #002025;
     border-radius: 20px;
     opacity: 100;
     border: 2px solid #ff2025;                   
        }""")

是这样的;

您会看到圆角,但小部件未圆角。是长方形。这是我的第一个问题。我的第二个问题是 您会看到 QMediaPlayer 的角不是圆角的,因为它溢出了 QWidget。我该如何解决这个问题?

下面是我的所有代码;

# PyQt5 Video player
#!/usr/bin/env python

from PyQt5.QtCore import QDir, Qt, QUrl,QRect, pyqtSignal
from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtWidgets import (QApplication, QFileDialog, QHBoxLayout, QLabel,
        QPushButton, QSizePolicy, QSlider, QStyle, QVBoxLayout, QWidget,QProgressBar,QFrame)
from PyQt5.QtWidgets import QMainWindow,QWidget, QPushButton, QAction
from PyQt5.QtGui import QIcon
import sys,os

class VideoWindow(QMainWindow):
    closeSignal = pyqtSignal(int)

    def __init__(self, parent=None):
        super(VideoWindow, self).__init__(parent)

    def setupUi(self,window):
        self.window = window
        self.window.setFixedSize(784,442)
        #self.window.setFixedSize(884,542)
        self.window.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowStaysOnTopHint|Qt.WA_TranslucentBackground)

        self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface)

        widget = QWidget(self.window)

        widget.setObjectName('Custom_Widget')
        widget.setStyleSheet("""
        #Custom_Widget {
            background: #002025;
            border-radius: 20px;
            opacity: 100;
            border: 2px solid #ff2025;
        }
        """)

        videoWidget = QVideoWidget(widget)
        videoWidget.setGeometry(QRect(0,0,784, 442))

        self.mediaPlayer.setVideoOutput(videoWidget)
        self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(os.getcwd() + "\\logo-anim.avi")))
        self.mediaPlayer.play()
        #self.mediaPlayer.stateChanged.connect(lambda x: self.closeSignal.emit(x))
        self.mediaPlayer.stateChanged.connect(lambda x: sys.exit())
        
        self.window.setCentralWidget(widget)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = QMainWindow()
    player = VideoWindow()
    player.setFixedSize(784, 442)
    player.setupUi(w)
    w.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt5 qframe


    【解决方案1】:

    你的代码有很多问题和误解,也很混乱。

    • 您正在创建一个您没有使用的 QMainWindow (VideoWindow)。
    • 您将视频小部件添加为 QWidget 的子小部件,并为 QMainWindow、QWidget 和 QVideoWidget 设置相同的几何图形;如果它们都具有相同的几何图形,您会如何期望它们有边界?
    • 如果你想要一个有边框但没有其他功能的普通小部件,那么使用 QMainWindow 不仅没有必要,而且是错误的:QMainWindows 提供了内部布局、支持状态栏、工具栏、停靠小部件和菜单等功能,你可以显然不会使用;将使用 QWidget。
    • 如果一个小部件将有子部件,则应避免使用固定几何形状,而应始终使用布局管理器,即使只有 一个小部件;
    • 通过样式表设置圆角边框不会改变小部件的实际形状(始终为矩形),您需要改为应用 遮罩。李>
    • 您试图将Qt.WidgetAttribute 用于窗口标志,这不仅非常错误,而且由于它不是窗口标志而导致一些问题;此类属性必须与 setAttribute() 一起使用。
    • 设置无框架标志可能会阻止在大多数系统中移动窗口,您应该通过提供适当的鼠标交互来解决这个问题。
    • 通常最好为新 Qt 对象设置父对象(除非它们是小部件),尤其是当它们使用线程/并发处理(如 QMediaPlayer)时,因此当父对象存在时它们将被正确删除,并且系统资源是正确释放。

    这是您的代码的修订版。

    class VideoWindow(QWidget):
        closeSignal = pyqtSignal(int)
    
        def __init__(self, parent=None):
            super(VideoWindow, self).__init__(parent)
    
            self.setFixedSize(784,442)
            self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowStaysOnTopHint)
            self.setAttribute(Qt.WA_TranslucentBackground)
    
            self.setStyleSheet("""
            VideoWindow {
                background: #002025;
                border-radius: 20px;
                opacity: 100;
                border: 2px solid #ff2025;
            }
            """)
    
            layout = QHBoxLayout(self)
            videoWidget = QVideoWidget()
            layout.addWidget(videoWidget)
    
            self.mediaPlayer = QMediaPlayer(self, QMediaPlayer.VideoSurface)
            self.mediaPlayer.setVideoOutput(videoWidget)
            self.mediaPlayer.setMedia(QMediaContent(QUrl.fromLocalFile(os.getcwd() + "/test.mp4")))
            self.mediaPlayer.play()
    
            self.startPos = None
    
        def mousePressEvent(self, event):
            self.startPos = event.pos()
    
        def mouseMoveEvent(self, event):
            if self.startPos:
                self.move(self.pos() + (event.pos() - self.startPos))
    
        def mouseReleaseEvent(self, event):
            self.startPos = None
    
        def resizeEvent(self, event):
            path = QPainterPath()
            path.addRoundedRect(QRectF(self.rect()), 20, 20)
            reg = QRegion(path.toFillPolygon().toPolygon())
            self.setMask(reg)
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        player = VideoWindow()
        player.setFixedSize(784, 442)
        player.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 我认为我应用于 QWidget 的操作会在它们重叠时反映在 QMediaPlayer 上。我想这就是我从不同网站裁剪代码的方式:) 实际上我刚刚开始使用 PyQt5,我想为我的应用程序创建一个启动画面。我不知道我有这么多错误,非常感谢你的帮助。最后,您有什么可以推荐的学习 PyQt5 的资源吗?
    • 资源很多,他们的目标主要取决于编程知识和经验,所以只有你知道什么是最好的。请注意,QMediaPlayer 用于显示多媒体内容,这通常不是启动屏幕的目的,考虑将视频导出为 GIF 并加载 QMovie:它使用更少的资源,加载速度更快,更适合这种情况。还要记住,有 QSplashScreen 类(必须正确子类化才能正确显示流畅的动画)
    • 好的,感谢您所做的一切。我会尝试你的建议。
    猜你喜欢
    • 1970-01-01
    • 2012-12-25
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2012-06-01
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多