【问题标题】:Overlay text over a specific widget (transparent labels) in pyqt4在pyqt4中的特定小部件(透明标签)上覆盖文本
【发布时间】:2012-12-12 02:21:54
【问题描述】:

考虑修改answer from @ekhumoro,如下所示。

QWidget 中嵌入了一个 mplayer。现在我想在视频上叠加一些文字。但是我下面的方法不起作用(标签的背景不透明,以至于只能看到视频和文本)。有什么办法解决吗?

更一般地说:如何使透明标签定位在自定义小部件(在我的例子中是 mplayer-widget)上?

如果无法完全达到我想要的效果,那么只需显示冻结视频的最后一帧(或预定义的帧)并在其上显示一些文本就足够了。

请注意,在稍后阶段,我希望覆盖视频的文本随时间而变化,因此解决方案应该已经考虑到这一点。

为了提高透明度,请注意我使用的是 linux 环境,这应该特别适用于xmonad

import mpylayer
from PyQt4 import QtGui, QtCore

class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.container = QtGui.QWidget(self)

        #self.container.setStyleSheet('background: black')
        self.button = QtGui.QPushButton('Open', self)
        self.button.clicked.connect(self.handleButton)


        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.button)

        self.layout.addWidget(self.container)

        self.mplayer = mpylayer.MPlayerControl(
            'mplayer', ['-wid', str(self.container.winId())])


        self.label = QtGui.QLabel('Some text\n and more',self)
        self.label.move(100,100)
        self.label.setGeometry(200,200,900,300)

        #This doesn't work
        self.label.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        #opacity doesn't work
        self.label.setStyleSheet("QLabel {font-size: 100px; opacity:0.5}")


    def handleButton(self):
        path = QtGui.QFileDialog.getOpenFileName()
        if not path.isEmpty():
            self.mplayer.loadfile(unicode(path))

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(640, 480)
    window.show()
    sys.exit(app.exec_())

这是我的非工作方法的屏幕截图:

这是我想用gimp 伪造的(也许我应该使用红色字体颜色,但这应该只是简单的css):

编辑 以下是我尝试将 X.Jacobs 答案改编为我的示例的方法。但是它不起作用。仅当我调整窗口大小时,覆盖的文本/行才会在视频上显示一毫秒,然后再次消失(在这两种情况下,如果视频正在运行并且正在暂停)。

import mpylayer
from PyQt4 import QtGui, QtCore

class overlayLabel(QtGui.QLabel):    
    def __init__(self, parent=None):        
        super(overlayLabel, self).__init__(parent)
        self.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)

        self.setText("OVERLAY TEXT")
        self.setStyleSheet("QLabel {font-size: 100px;}")
        self.setGeometry(200,200,900,300)

class overlay(QtGui.QWidget):    
    def __init__(self, parent=None):        
        super(overlay, self).__init__(parent)

        palette = QtGui.QPalette(self.palette())
        palette.setColor(palette.Background, QtCore.Qt.transparent)

        self.setPalette(palette)

    def paintEvent(self, event):        
        painter = QtGui.QPainter()
        painter.begin(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing)
        painter.fillRect(event.rect(), QtGui.QBrush(QtGui.QColor(255, 255, 255, 27)))
        painter.drawLine(self.width()/8, self.height()/8, 7*self.width()/8, 7*self.height()/8)
        painter.drawLine(self.width()/8, 7*self.height()/8, 7*self.width()/8, self.height()/8)
        painter.setPen(QtGui.QPen(QtCore.Qt.NoPen))        


class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.container = QtGui.QWidget(self)

        #self.container.setStyleSheet('background: black')
        self.button = QtGui.QPushButton('Open', self)
        self.button.clicked.connect(self.handleButton)


        self.layout = QtGui.QVBoxLayout(self)
        self.layout.addWidget(self.button)

        self.layout.addWidget(self.container)

        self.mplayer = mpylayer.MPlayerControl(
            'mplayer', ['-wid', str(self.container.winId())])



        ## Both versions don't work:

        #self.label = overlay(self.container)
        self.label = overlayLabel(self.container)



    def handleButton(self):
        path = QtGui.QFileDialog.getOpenFileName()
        if not path.isEmpty():
            self.mplayer.loadfile(unicode(path))


if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    window.resize(640, 480)
    window.show()
    sys.exit(app.exec_())

【问题讨论】:

    标签: python qt4 pyqt pyqt4 pyside


    【解决方案1】:

    查看此示例叠加小部件,您可以根据自己的需要进行调整:

    #!/usr/bin/env python
    #-*- coding:utf-8 -*-
    
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    
    class overlay(QWidget):    
        def __init__(self, parent=None):        
            super(overlay, self).__init__(parent)
    
            palette = QPalette(self.palette())
            palette.setColor(palette.Background, Qt.transparent)
    
            self.setPalette(palette)
    
        def paintEvent(self, event):        
            painter = QPainter()
            painter.begin(self)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.fillRect(event.rect(), QBrush(QColor(255, 255, 255, 127)))
            painter.drawLine(self.width()/8, self.height()/8, 7*self.width()/8, 7*self.height()/8)
            painter.drawLine(self.width()/8, 7*self.height()/8, 7*self.width()/8, self.height()/8)
            painter.setPen(QPen(Qt.NoPen))        
    
    class windowOverlay(QWidget):
        def __init__(self, parent=None):
            super(windowOverlay, self).__init__(parent)
    
            self.editor = QTextEdit()
            self.editor.setPlainText("OVERLAY"*100)
    
            self.button = QPushButton("Toggle Overlay")
    
            self.verticalLayout = QVBoxLayout(self)
            self.verticalLayout.addWidget(self.editor)
            self.verticalLayout.addWidget(self.button)
    
            self.overlay = overlay(self.editor)
            self.overlay.hide()
    
            self.button.clicked.connect(lambda: self.overlay.setVisible(False) if self.overlay.isVisible() else self.overlay.setVisible(True))
    
        def resizeEvent(self, event):    
            self.overlay.resize(event.size())
            event.accept()
    
    if __name__ == "__main__":
        import  sys
    
        app = QApplication(sys.argv)
        main = windowOverlay()
        main.show()
        sys.exit(app.exec_())
    

    要覆盖文本,请使用以下内容:

    class overlayLabel(QLabel):    
        def __init__(self, parent=None):        
            super(overlayLabel, self).__init__(parent)
            self.setAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
    
            self.setText("OVERLAY TEXT")
    

    【讨论】:

    • 谢谢,但我不太明白它的作用/如何申请。对我来说,似乎只是让文本变灰......关键是我只想看到(黑色)文本和背景中的视频,而不是隐藏部分视频的标签背景......
    • @student 见我的updated answer,我对其进行了修改以使覆盖更明显
    • 谢谢。如果我理解正确,overlay 类将替换我帖子示例中的标签,QTextEdit 对应于我的mplayer 容器?如果是这样,我怎么能在你的 overlay 类中写文本(而不是画一些线)?
    • @student checkout my re-updated answer,我添加了一个overlayLabel,它在QWidget顶部显示文本
    • 我不确定 pyQt 是如何工作的,但您可能需要查看 QWidgets 的 autoFillBackground 设置,并确保您的叠加层为 false。您可能还想查看一些相关的窗口提示(在 autoFillBackground 设置的文档中提到)。
    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 2013-04-18
    相关资源
    最近更新 更多