如何在QTextEdit中创建完全透明效果

1 投票
1 回答
8351 浏览
提问于 2025-04-16 22:52

我已经尝试了很多天,想找出一种方法来创建一个透明的QTextEdit,但里面的文字却是清晰可见的。因为“透明”这个词常常让人困惑,我把QTextEdit的“透明”定义为:能够看到QTextEdit里的文字,同时这些文字可以覆盖在主窗口后面的任何东西上(比如桌面背景、Windows Media Player等)。如果可能的话,我希望能设置不同程度的透明度,并且希望它在不同系统上都能兼容,但这不是必须的。

我还是个新手,才刚用PyQt4三周,Python 3.x也就用了几个月,这就是我所有的编程经验。我一直在试图理解PyQt的文档,但它写得像是假设读者已经是有几十年经验的GUI程序员,更不用说还要懂C++了。而且,当这个问题在网上被提问时,似乎总是没有得到一个既有详细说明又能普遍适用的解决方案。

这让我很惊讶,因为这看起来是人们想要做的一个基本操作。

这个解决方案是有效的,但似乎只对显示透明图像有用。我也不是很理解,因为简单地把基类从QWidget改成QMainWindow就会导致整个程序失败。

http://www.loopbacking.info/blog/2008/07/11/transparent-windows-howto/

下面这个链接总结了人们通常建议的解决类似问题的方法、它们的缺陷以及为什么不奏效,但不幸的是,它们使用的是Qt的C++版本,而且对我目前的技能来说有点复杂。

http://www.qtcentre.org/threads/18072-How-to-set-Qt-window-transparent

我的系统是Windows 7 Ultimate 32位,使用的是戴尔Latitude D830,显卡是Quadro NVS 140,驱动版本是目前最新的(Verde 275.33)。我的PyQt版本是4.8(PyQt-Py3.2-x86-gpl-4.8.5-1.exe Windows 32位安装包),同时我也在使用Python 3.2.1(开源版本)。

下面是我代码的一个基本示例,相关(但失败的)代码行已被注释掉:

当我尝试注释掉的代码时,通常看到的颜色就是黑色。而且,当我调整窗口大小时,黑暗的程度会随机变化,最大化时主窗口的显示似乎也会出现问题。

我非常希望能得到任何帮助!

import sys
import PyQt4
from PyQt4 import QtGui, QtCore

class Transparent(QtGui.QMainWindow):
    def __init__(self,parent = None):
        QtGui.QMainWindow.__init__(self,parent)
        self.initialize()

    def initialize(self):
        #self.colorset(self,'Window',200,255,100,20) 
        #self.colorset(self,'Base',200,255,100,20)
        #self.setBackgroundRole(QtGui.QPalette.Base)
        #self.setAttribute(QtCore.Qt.WA_NoSystemBackground)
        #self.setAutoFillBackground(True)
        #self.mask()
        self.setWindowTitle("Chernobyl-like Failure")

        self.answerlabel = QtGui.QLabel('Text Response Display')
        self.answerlabel.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised)
        self.answerlabel.setMinimumHeight(25)
        self.questionlabel = QtGui.QLabel("Question:")
        self.questionlabel.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised)

        self.questionbox = QtGui.QLineEdit()
        self.questionbox.setMinimumWidth(500)

        self.askbutton = QtGui.QPushButton("Ask it!")

        self.historybox = QtGui.QTextEdit('Question & Answer history will be displayed here')
        self.historybox.setReadOnly(True)
        #self.colorset(self.historybox,'Base',200,255,100,127) 
        self.grid = QtGui.QGridLayout()
        widgetlist = [['answerlabel',0,0,1,3],['questionlabel',1,0,1,1],
                      ['questionbox',1,1,1,1],['askbutton',1,2,1,1],['historybox',2,0,1,3]]
        for widget in widgetlist:
            self.grid.addWidget(eval("self.{0}".format(widget[0])),*widget[1:])

        self.centralwidget = QtGui.QFrame()
        self.centralwidget.setFrameStyle(QtGui.QFrame.Box|QtGui.QFrame.Raised)
        self.centralwidget.setLineWidth(5)
        self.centralwidget.setLayout(self.grid)
        #self.colorset(self.centralwidget,'Base',200,255,100,127) 
        self.setCentralWidget(self.centralwidget)

    def colorset(self,widget,part,h,s,l,a):
        pal = widget.palette()
        color = QtGui.QColor()
        color.setHsl(h,s,l,a)
        pal.setColor(eval('QtGui.QPalette.{0}'.format(part)),color)
        widget.setPalette(pal)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    main_window = Transparent()
    main_window.show()
    sys.exit(app.exec_())

1 个回答

1

要让你的主窗口变得透明,你需要设置一个叫做 Qt.WA_TranslucentBackground 的属性(用 setAttribute(Qt.WA_TranslucentBackground) 来实现)。在 Windows 系统下,你还需要在主窗口上设置 Qt.FramelessWindowHint 属性。根据文档,没有边框的窗口用户无法通过窗口系统来移动或调整大小。所以,如果你想要这样的功能,就得自己手动实现。这里有一个讨论帖,里面用 C++ 举了个例子。

一旦你有了透明的主窗口,你可以通过设置背景颜色为 RGBA 值来控制它和任何子控件的透明度。下面是一个简单的例子,

from PyQt4 import QtGui, QtCore
import sys

class Main(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Main, self).__init__(parent)

        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        frame = QtGui.QFrame(parent=self)
        frame.setStyleSheet("QFrame {background: rgba(0,255,0,20%)}")
        box=QtGui.QHBoxLayout()

        edit = QtGui.QTextEdit()
        edit.setStyleSheet("background: rgba(0,0,255,20%)")
        box.addWidget(edit)

        edit2=QtGui.QTextEdit()
        edit2.setStyleSheet("background: rgb(255,0,0)")
        box.addWidget(edit2)
        frame.setLayout(box)

        pushbutton = QtGui.QPushButton('Quit')
        pushbutton.clicked.connect(self.close)
        box.addWidget(pushbutton)

        self.setCentralWidget(frame)        

if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    main = Main()
    main.show()

    app.exec_()

撰写回答