【问题标题】:Pseudo transparency with PyQTPyQT 的伪透明
【发布时间】:2012-11-13 11:33:23
【问题描述】:

我想通过使用 PyQt 截取窗口后面的内容来创建一个伪透明窗口。以下代码截图:

#!/usr/bin/python3

from PyQt4.QtGui import *

app = QApplication([])
widget = QWidget()
widget.setLayout(QVBoxLayout())
label = QLabel()
widget.layout().addWidget(label)

def shoot():
    geometry = widget.geometry()
    widget.hide()
    label.setPixmap(QPixmap.grabWindow(QApplication.desktop().winId(), x = geometry.x(), y = geometry.y(), height = geometry.height(), width = geometry.width())
    widget.show()

widget.layout().addWidget(QPushButton('Screenshot', clicked = shoot))
widget.show()
app.exec_()

但是,虽然有 widget.hide(),但窗口本身出现在屏幕截图上。我怎样才能避免这种情况?

【问题讨论】:

  • 您是否尝试过在widget.hide() 和设置标签的像素图之间等待(time.sleep())一段时间?截屏时,小部件可能尚未隐藏。或者,您是否尝试过使用widget.setAttribute(Qt.WA_TranslucentBackground, True) 的实际透明度?
  • 谢谢,如果我在 widget.hide() 之后添加 0.3 秒的睡眠,它实际上可以工作。但是我怎么知道要等多久呢?有没有办法简单地等到隐藏事件完成?

标签: python pyqt transparency screenshot


【解决方案1】:

这是我写的内容,基本上可以满足您的需求。它使用可调整大小的 Qt 窗口来截取其背后的任何内容。到目前为止,此脚本仅适用于 1 个屏幕。深入了解QScreenQApplication 可能会给您答案,以使其可扩展。

import sys
import io
from PySide2.QtWidgets import QApplication, QWidget, QPushButton
from PySide2.QtCore import Qt, QBuffer
from PIL import Image


class Screenshooter(QWidget):
    def __init__(self, parent):
        super().__init__()
        self.parent = parent
        self.setAttribute(Qt.WA_TranslucentBackground, True)
        self.resize(640, 480)
        self.snapBtn = QPushButton("Capture", self)
        self.snapBtn.clicked.connect(self.take_screenshot)
        self.show()

    def take_screenshot(self):
        geometry = self.geometry()
        screen = self.parent.screenAt(self.pos())
        full_screenshot = screen.grabWindow(
            0,
            geometry.x(),
            geometry.y(),
            geometry.width(),
            geometry.height()
        )
        full_image = full_screenshot.toImage()
        buffer = QBuffer()
        buffer.open(QBuffer.ReadWrite)
        full_image.save(buffer, 'PNG')
        im = Image.open(io.BytesIO(buffer.data()))
        im.show()
        buffer.close()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = Screenshooter(app)
    sys.exit(app.exec_())

【讨论】:

    【解决方案2】:

    我认为app.processEvents() 应该也可以工作,而不是睡不知道的时间。这会强制 Qt 应用程序在继续之前完成正在进行的事情——例如隐藏小部件。 This 是一个相关问题,在其中一个答案中对此进行了讨论。

    【讨论】:

    • 似乎 processEvents() 持续时间不够长。我也试过 while self.isHidden() == False: sleep(0.1),但这也没有等待足够长的时间。窗口闪烁了一下,但屏幕截图没有显示它后面的桌面。
    猜你喜欢
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2018-05-10
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    相关资源
    最近更新 更多