调用 QScreen.grabWindow() 时输入错误

Type error when calling QScreen.grabWindow()

我正在尝试使用 PySide(和 return QPixmap)截屏。这是一个更大脚本的一部分。不幸的是,我现在 运行 撞墙了。

这是我正在尝试开始工作的简化片段:

from PySide2 import QtGui, QtWidgets

screen = QtWidgets.QApplication.primaryScreen()
winid = QtWidgets.QApplication.desktop().winId()
pixmap = screen.grabWindow(winid)

label = QtWidgets.QLabel("test")
label.setPixmap(pixmap)
label.show()

执行此操作时,会抛出以下错误:

TypeError: 'PySide2.QtGui.QScreen.grabWindow' called with wrong argument types:
PySide2.QtGui.QScreen.grabWindow(int)
Supported signatures:
PySide2.QtGui.QScreen.grabWindow(quintptr, int = 0, int = 0, int = -1, int = -1)

我使用的是 PySide 版本 2.0.0~alpha0(这是我正在使用的主机应用程序附带的版本)。我已经在使用 PySide2 5.12.2 版的主机应用程序的新版本中测试了相同的代码,它按预期执行,没有任何错误......但是,我仅限于使用旧版本的主机应用程序。

有人知道解决方法吗?

首先想到的是使用 PyQt5 生成 QPixmap,并让 PySide 从那里获取它,但是在测试时发现 PyQt QPixmap 与 PySide 不兼容。将整个脚本移植到 PyQt 也不是一个选项。

如果您可以使用 PyQt5 获得 QPixmap,那么您可以将该信息转换为通用数据类型作为 PySide2 可以读取的字节:

import sys

from PySide2 import QtCore, QtGui, QtWidgets


def take_screenshot():
    from PyQt5 import QtCore as pyqt5c
    from PyQt5 import QtWidgets as pyqt5w

    screen = pyqt5w.QApplication.primaryScreen()
    winid = pyqt5w.QApplication.desktop().winId()
    pixmap = screen.grabWindow(winid)

    ba = pyqt5c.QByteArray()
    buff = pyqt5c.QBuffer(ba)
    pixmap.save(buff, "PNG")
    return ba.data()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    data = take_screenshot()

    pixmap = QtGui.QPixmap()
    pixmap.loadFromData(data)

    label = QtWidgets.QLabel()
    label.setPixmap(pixmap)
    label.show()

    sys.exit(app.exec_())

我来晚了一点,但在使用 QPixmap 保存屏幕截图时遇到了类似的问题。我的解决方法是将 winId 转换为 long int。

import maya.OpenMayaUI as _omui
from PySide2 import QtWidgets, QtGui
from shiboken2 import wrapInstance

def get_maya_main_window():
    win = _omui.MQtUtil_mainWindow()
    ptr = wrapInstance(long(win), QtWidgets.QMainWindow)
    return ptr

main_window_id = get_maya_main_window().winId()
long_win_id = long(main_window_id)

frame = QtGui.QPixmap.grabWindow(long_win_id)
path = <your-path-here>

frame.save(path)