使用 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 代替 PyQt4 作为 matplotlib Qt4Agg 后端的先决条件
PySide/PyQt4:向 QTableWidget Horizontal (column) Header 添加一个复选框