'QPixmap' has no attribute 'grabWindow' - python

I am trying convert my code from PyQt4 to PyQt5 but I am getting errors.
import sys
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication
from datetime import datetime
date = datetime.now()
filename = date.strftime('%Y-%m-%d_%H-%M-%S.jpg')
app = QApplication(sys.argv)
QPixmap.grabWindow(QApplication.desktop().winId()).save(filename, 'jpg')
Traceback (most recent call last):
File "C:\Python34\Projects\name.py", line 9, in <module>
QPixmap.grabWindow(QApplication.desktop().winId()).save(filename, 'jpg')
AttributeError: type object 'QPixmap' has no attribute 'grabWindow'

You should use QScreen::grabWindow() instead. QPixmap::grabWindow() is deprecated in Qt 5.0 because:
there might be platform plugins in which window system identifiers (WId) are local to a screen.

grabWindow method is now available in QScreen class.
You need to create QScreen object, initialize it with ex. QtGuiApplication.primaryScreen() and then grab the screen
screen.grabWindow(QApplication.desktop().winId())

Full example for PyQt5
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QPixmap, QScreen
from datetime import datetime
date = datetime.now()
filename = date.strftime('%Y-%m-%d_%H-%M-%S.jpg')
app = QApplication(sys.argv)
QScreen.grabWindow(app.primaryScreen(),
QApplication.desktop().winId()).save(filename, 'png')

Related

Qt Designer error with Python throwing error when I try to load image

I'm trying to load a logo into a python scripts UI. I'm using Qt Designer and I created a label and set pixmap to the image. The image loads fine in the designer but when I import the ui file into the python script I get this error message
C:\Users\Mason\AppData\Local\Continuum\anaconda3\python.exe "C:/Users/Mason/PycharmProjects/Inspector/Tester/main.py"
Traceback (most recent call last):
File "C:/Users/Mason/PycharmProjects/Inspector/Tester/main.py", line 9, in <module>
UIClass, QtBaseClass = uic.loadUiType("ui5.ui")
File "C:\Users\Mason\AppData\Local\Continuum\anaconda3\lib\site-packages\PyQt5\uic\__init__.py", line 201, in loadUiType
exec(code_string.getvalue(), ui_globals)
File "<string>", line 30
import 3_rc
I still get that error even if I take the image out of the ui file and reload it. What am I doing wrong?
from PyQt5 import QtCore, uic, QtWidgets
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.uic import loadUi
from PyQt5.QtGui import QIcon, QPixmap
import sys
UIClass, QtBaseClass = uic.loadUiType("ui5.ui")
class MyApp(UIClass, QtBaseClass):
def __init__(self):
UIClass.__init__(self)
QtBaseClass.__init__(self)
self.setupUi(self)
self.pushButton.clicked.connect(self.on_pushbutton_click)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
Qt relies on a resource system for images and other assets. When you add an image in qt designer, it creates a resource file. You have to convert that resource file, just like with a ui file (uic is a shortcut to this process). The autogenerated ui file you get with uic is looking for that resource file, but can't find it.
You can convert your resource file to python with this, depending on your qt version:
pyrcc5 -o 3_rc.py your_resource_file_here.qrc
More info:
Related question: Importing resource file to PyQt code?
https://www.riverbankcomputing.com/static/Docs/PyQt4/resources.html
https://www.riverbankcomputing.com/static/Docs/PyQt5/resources.html

snapshoot of widget pyqt5

Hi every one I am traying to get a snapshoot of a widget using pyqt5 I am using this code but I can't create an object of the class QScreen
I get an error :
PyQt5.QtGui.QScreen cannot be instantiated or sub-classed
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QPixmap,QScreen
from PyQt5.QtWidgets import QApplication
from datetime import datetime
date = datetime.now()
filename = date.strftime('%Y-%m-%d_%H-%M-%S.jpg')
app = QApplication(sys.argv)
sc=QtGui.QScreen()
sc.grabWindow(QApplication.desktop().winId()).save(filename, 'jpg')
You can get a reference to the screen with :
sc = app.screens()[0]
This method returns a list of screens, i assume you want the first (with index [0])

Python - opencv - pyqt5

When I try to import cv2 when using pyqt5 I have this error :
ImportError: /lib64/libQt5Widgets.so.5: symbol _ZN23QPlatformSystemTrayIcon16staticMetaObjectE, version Qt_5 not defined in file libQt5Gui.so.5 with link time reference
If I only import cv2 or pyqt5 there are no errors, but together it doesn't work.
What can i do to resolve my problem ?
import sys
import os
import cv2
from PyQt5.QtWidgets import QApplication
import mainWindow
class Application:
def __init__(self):
self.mainWindow = mainWindow.MainWindow()
if __name__ == '__main__':
app = QApplication(sys.argv)
application = Application()
sys.exit(app.exec_())

How to get maya main window pointer using PySide?

I've used PyQt4 in maya quite a bit, and generally I've found it quite easy to switch to PySide, but I'm having trouble getting the pointer to the main window. Perhaps someone can understand what's going wrong.
Here's what I do in PyQt4:
import sip, PyQt4.QtCore
import maya.OpenMayaUI as mui
ptr = mui.MQtUtil.mainWindow()
parent = sip.wrapinstance(long(ptr), PyQt4.QtCore.QObject)
This works fine. When I try the same in PySide:
import sip, PySide.QtCore
import maya.OpenMayaUI as mui
ptr = mui.MQtUtil.mainWindow()
parent = sip.wrapinstance(long(ptr), PySide.QtCore.QObject)
I get the following error:
# Error: wrapinstance() argument 2 must be sip.wrappertype, not Shiboken.ObjectType
# Traceback (most recent call last):
# File "<maya console>", line 4, in <module>
# TypeError: wrapinstance() argument 2 must be sip.wrappertype, not Shiboken.ObjectType #
Anyone know what's going wrong?
You need to import shiboken instead of sip and pass QWidget to wrapInstance instead of QObject
Edit: Maya2017 contains shiboken2 and PySide2 instead of shiboken and PySide as pointed out in comments below.
import shiboken
from PySide import QtGui, QtCore
import maya.OpenMayaUI as apiUI
def getMayaWindow():
"""
Get the main Maya window as a QtGui.QMainWindow instance
#return: QtGui.QMainWindow instance of the top level Maya windows
"""
ptr = apiUI.MQtUtil.mainWindow()
if ptr is not None:
return shiboken.wrapInstance(long(ptr), QtGui.QWidget)
Please note that sip has wrapinstance in which i is not capital but in shiboken.wrapInstance i is capital.
shiboken.wrapInstance() requires wrapertype as a second argument, so you can pass QWidget as a second argument.
Because the previous answer has become somewhat out-of-date, here is a more current version to save someone the trouble of having to update it themselves.
Two approaches for getting the maya main window:
using PySide2:
from PySide2 import QtWidgets
global app
app = QtWidgets.QApplication.instance() #get the qApp instance if it exists.
if not app:
app = QtWidgets.QApplication(sys.argv)
def getMayaMainWindow():
mayaWin = next(w for w in app.topLevelWidgets() if w.objectName()=='MayaWindow')
return mayaWin
print(getMayaMainWindow())
Using shiboken2 and the maya api:
import maya.OpenMayaUI as apiUI
from PySide2 import QtWidgets
try:
import shiboken2
except:
from PySide2 import shiboken2
def getMayaMainWindow():
ptr = apiUI.MQtUtil.mainWindow()
mayaWin = shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget)
return mayaWin
print(getMayaMainWindow())
depending on your needs, the following more modern code might be easier too use.
since maya now has a build in method to access the main window in qt
import pymel.core as pm
mayaWindow = pm.ui.Window("MayaWindow").asQtObject()
your_widget.setParent(mayaWindow)

Screenshot of a window using python

I'm trying to take a screenshot of the curent window using a python script on linux.
I curently have a script which takes a screenshot of the entire screen:
import sys
from PyQt4.QtGui import QPixmap, QApplication
from datetime import datetime
date = datetime.now()
filename = date.strftime('%Y-%m-%d_%H-%M-%S.jpg')
app = QApplication(sys.argv)
QPixmap.grabWindow(QApplication.desktop().winId()).save(filename, 'jpg')
But a would like to have only the selected window. I know that the problem comes from grabWindow. But I don't know how to resolve it.
simply replace
QApplication.desktop()
with the widget you want to take the screenshot of.
import sys
from PyQt4.QtGui import *
from datetime import datetime
date = datetime.now()
filename = date.strftime('%Y-%m-%d_%H-%M-%S.jpg')
app = QApplication(sys.argv)
widget = QWidget()
# set up the QWidget...
widget.setLayout(QVBoxLayout())
label = QLabel()
widget.layout().addWidget(label)
def shoot():
p = QPixmap.grabWindow(widget.winId())
p.save(filename, 'jpg')
label.setPixmap(p) # just for fun :)
print "shot taken"
widget.layout().addWidget(QPushButton('take screenshot', clicked=shoot))
widget.show()
app.exec_()
Since Qt5, grabWindow and grabWidget are obsolete (see Obsolete Members for QPixmap)
Instead, you can use QWidget.grab()
p=widget.grab()
Alternatively, instead of
p = QPixmap.grabWindow(widget.winId())
you can also use
p = QPixmap.grabWidget(widget)
PyQt5 update
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtGui import QPixmap, QScreen
from datetime import datetime
date = datetime.now()
filename = date.strftime('%Y-%m-%d_%H-%M-%S.jpg')
app = QApplication(sys.argv)
QScreen.grabWindow(app.primaryScreen(),
QApplication.desktop().winId()).save(filename, 'png')

Categories

Resources