使用 PyQt4 或 PySide 捕获屏幕,除了特定的小部件?

Posted

技术标签:

【中文标题】使用 PyQt4 或 PySide 捕获屏幕,除了特定的小部件?【英文标题】:Capture Screen with PyQt4 or PySide, except specific widget? 【发布时间】:2019-05-06 04:18:02 【问题描述】:

我正在尝试捕获我的 pyqt4 应用程序半透明区域中的屏幕区域,但我想在捕获中排除小部件“betwn = QPushButton('test')”,我正在尝试使用隐藏小部件hide() 像这样: betwn.hide(),因为在捕获之前被排除,但不起作用,即使隐藏的“betwn”也会被捕获。

这是我的 PyQt4 代码:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from datetime import datetime

app = QApplication(sys.argv)
widget = QWidget()
widget.setLayout(QVBoxLayout())
widget.setAttribute(Qt.WA_TranslucentBackground)

label = QLabel()
widget.layout().addWidget(label)

def capture():
    p = QPixmap.grabWindow(QApplication.desktop().winId(),widget.geometry().x(),widget.geometry().y(),widget.geometry().width(),widget.geometry().height())
    label.setPixmap(p)
def shoot():
    betwn.hide()
    capture()
    betwn.show()
button = QPushButton('take screenshot', clicked=shoot)
betwn = QPushButton('test')
widget.layout().addWidget(button)
widget.layout().addWidget(betwn)

widget.show()
app.exec_()

这是我的 PySide 代码:

import sys
from PySide.QtGui import *
from PySide.QtCore import *
from datetime import datetime

app = QApplication(sys.argv)
widget = QWidget()
widget.setLayout(QVBoxLayout())
widget.setAttribute(Qt.WA_TranslucentBackground)

label = QLabel()
widget.layout().addWidget(label)

def capture():
    p = QPixmap.grabWindow(QApplication.desktop().winId(),widget.geometry().x(),widget.geometry().y(),widget.geometry().width(),widget.geometry().height())
    label.setPixmap(p)
def shoot():
    betwn.hide()
    capture()
    betwn.show()
button = QPushButton('take screenshot', clicked=shoot)
betwn = QPushButton('test')
widget.layout().addWidget(button)
widget.layout().addWidget(betwn)

widget.show()
app.exec_()

如何在捕获中排除小部件“betwn = QPushButton('test')”?或者如果您知道使用窗口的其他方法来捕获桌面区域而不捕获窗口,使用窗口的坐标和宽度和高度?

像这样:

QPixmap.grabWindow(QApplication.desktop().winId(),widget.geometry().x(),widget.geometry().y(),widget.geometry().width(),widget.geometry().height());

【问题讨论】:

【参考方案1】:

当你调用 hide 方法时,并不意味着按钮会在那一刻被关闭,因为它涉及到在同步任务结束后结束的重绘过程,在这些情况下你必须给 Qt 足够的时间去做这项工作是可以完成的。制作一个 QTimer::singleShot()。

app = QApplication(sys.argv)
widget = QWidget()
widget.setLayout(QVBoxLayout())
widget.setAttribute(Qt.WA_TranslucentBackground)

label = QLabel()
widget.layout().addWidget(label)


def capture():
    p = QPixmap.grabWindow(
        QApplication.desktop().winId(), 
        *widget.geometry().getRect()
    )
    label.setPixmap(p)
    betwn.show()


def shoot():
    betwn.hide()
    QTimer.singleShot(1, capture)


button = QPushButton("take screenshot", clicked=shoot)
betwn = QPushButton("test")
widget.layout().addWidget(button)
widget.layout().addWidget(betwn)

widget.show()
sys.exit(app.exec_())

【讨论】:

谢谢 eyllanesc,我可以在 QTimer.singleShot() 中使用线程(pyqt4 或 pyside)吗? @BennyWood 不,Qt 禁止从另一个线程直接与 GUI 交互,并且在您使用 QPixmap 与 GUI 记录时,您正在与 GUI 交互

以上是关于使用 PyQt4 或 PySide 捕获屏幕,除了特定的小部件?的主要内容,如果未能解决你的问题,请参考以下文章

matplotlib 不导入 PyQt4、PyQt5 或 PySide

关闭 PyQt 对话框会终止父进程? (PyQt4 / Pyside) 带有示例代码

将 vtkOrientationMarkerWidget 与 QVTKRenderWindowInteractor 一起使用 [PyQt4/PySide]

如何使用 PySide 获取 Maya 主窗口指针?

PySide 代替 PyQt4 作为 matplotlib Qt4Agg 后端的先决条件

PySide/PyQt4:向 QTableWidget Horizo​​ntal (column) Header 添加一个复选框