在pyqt4中的特定小部件(透明标签)上覆盖文本

2024-05-16 13:35:57 发布

您现在位置:Python中文网/ 问答频道 /正文

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

有一个mplayer嵌入在QWidget中。现在我想在视频上覆盖一些文本。但是我下面的方法不起作用(标签的背景是不透明的,所以只能看到视频和文本)。有办法修一下吗?

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

如果不可能达到我想要的效果,只显示的东西就足以冻结视频的最后一帧(或预定义的帧)并在其上显示一些文本。

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

为了提高透明度,需要注意的是,我使用的是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_())

以下是我的非工作方法的截图:

non working approach

下面是我想要用gimp伪造的东西(也许我应该用红色字体,但那应该只是简单的css):

gimp fake

编辑 下面是我如何尝试将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_())

Tags: pathimportself视频initcontainerdefbutton
1条回答
网友
1楼 · 发布于 2024-05-16 13:35:57

签出这个可以根据需要调整的覆盖小部件示例:

#!/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")

相关问题 更多 >