Trying to learn some PySide2 for Maya, but there is no clear documentation for PySide2 yet, so after searching in internet coming here again for help...
I will go straight to the problem -
from PySide2 import QtWidgets, QtGui
import maya.cmds as cmds
import maya.OpenMayaUI as mui
import shiboken2
def getMayaWindow():
pointer = mui.MQtUtil.mainWindow()
if pointer is not None:
return shiboken2.wrapInstance(long(pointer), QtWidgets)
Error: TypeError: file line 9: 'wrapInstance' called with wrong argument types:
wrapInstance(long, module)
Supported signatures:
wrapInstance(size_t, PyType) #
Best regards!
You should try to import modules by the following way:
import maya.cmds as cmds
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
import maya.OpenMayaUI as omui
try:
from shiboken import wrapInstance
except:
from shiboken2 import wrapInstance
def getMayaWindow():
pointer = omui.MQtUtil.mainWindow()
if pointer is not None:
return shiboken2.wrapInstance(long(pointer), QWidget)
getMayaWindow()
Related
how to make a EXE library much smaller in size and the exe startup faster?. My library is actually 580 MB and the startup time from the exe is around 10 seconds! Here is my main.py. Its imports data from interface. (sub program)
import sys
from datetime import datetime
from typing import Tuple
import numpy as np
import pandas as pd
from PyQt5.Qt import Qt
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtWidgets import QApplication, QLabel
from PyQt5.QtWidgets import (QWidget, QTableWidget, QTableWidgetItem)
from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtGui import QImage
from PyQt5.QtGui import QPixmap
from PyQt5.QtGui import QKeySequence
from PyQt5.QtGui import QMovie
from PyQt5.QtGui import QPainter
from PyQt5.QtGui import QPen
from PyQt5.QtGui import QColor
from PyQt5.QtGui import QFont
from PyQt5.QtCore import QTimer
from PyQt5.QtCore import Qt, QPoint
import cv2
import os
from sys import path
import shutil
import xlsxwriter
from tkinter import Tk, PhotoImage, Canvas
from interface import *
from line_detection import *
import openpyxl
from openpyxl.styles import Alignment, Font
import os.path
The header of interface.py looks like this:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import os.path
import pandas as pd
import numpy as np
from datetime import datetime
import xlsxwriter
import openpyxl
from openpyxl.styles import Alignment, Font
from openpyxl import load_workbook
In Inteface.py i do something like this:
MyApp = QtWidgets.QApplication(sys.argv)
V = MyApp.desktop().screenGeometry()
h = V.height()
w = V.width()
class Ui_Form(object):
def __init__(self):
self.show_label = True
self.show_groupbox = False
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(w, h)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.image_label1 = QtWidgets.QLabel(self.centralwidget)
self.image_label1.setGeometry(QtCore.QRect(0, 0, w, h))
self.image_label1.setText("")
self.image_label1.setObjectName("image_label1")
self.image_label1.setHidden(self.show_label)
self.image_label1.setDisabled(self.show_groupbox)
My cx_freeze (setup.py) looks like this. Its still including all packages and so on. How to make PyQT5 and other Packages much smaller when making a EXE
import sys
from cx_Freeze import setup, Executable
try:
from cx_Freeze.hooks import get_qt_plugins_paths
except ImportError:
include_files = []
else:
# Inclusion of extra plugins (new in cx_Freeze 6.8b2)
# cx_Freeze imports automatically the following plugins depending of the
# use of some modules:
# imageformats - QtGui
# platforms - QtGui
# mediaservice - QtMultimedia
# printsupport - QtPrintSupport
#
# So, "platforms" is used here for demonstration purposes.
include_files = get_qt_plugins_paths("PyQt5", "platforms")
# base="Win32GUI" should be used only for Windows GUI app
base = None
if sys.platform == "win32":
base = "Win32GUI"
build_exe_options = {
#[""]
"excludes": ["PyQt5.QtBluetooth",
"PyQt5.QtNetwork",
"PyQt5.QtNfc",
"PyQt5.QtWebChannel",
"PyQt5.QtWebEngine",
"PyQt5.QtWebEngineCore",
"PyQt5.QtWebEngineWidgets",
"PyQt5.QtWebKit",
"PyQt5.QtWebKitWidgets",
"PyQt5.QtWebsockets",
"PyQt5.QtSql",
"PyQt5.QtScript"],
"include_files": include_files,
}
bdist_mac_options = {
"bundle_name": "TEST",
}
bdist_dmg_options = {
"volume_label": "TEST",
}
executables = [Executable("main.py", base=base, target_name="TEST")]
setup(
name="TEST",
version="2.4",
description="TEST",
options={
"build_exe": build_exe_options,
"bdist_mac": bdist_mac_options,
"bdist_dmg": bdist_dmg_options,
},
executables=executables,
)
I am new on Python and PyQt5.
I used Qt Design to create a form for input.
I am able to print the 3 data that the user input but I don't know how to store them in a variable so that I can use them in the main program.
import PyQt5 as pq
import sys
from PyQt5 import QtWidgets, uic, QtGui
def Assigned(self):
Nx=call.Nx11.text()
Ny=call.Ny11.text()
Nxy=call.Nxy11.text()
Mx=call.Mx11.text()
My=call.My11.text()
Mxy=call.Mxy11.text()
print(Nx)
print(Ny)
print(Nxy)
return(Nx)
return(Ny)
return(Nxy)
app=QtWidgets.QApplication([])
call=pq.uic.loadUi("InputLoad.ui")
call.OKbutton.clicked.connect(Assigned)
call.show()
app.exec_()
Thank you in advance for any help.
Fab
Create a global variable and store them
import PyQt5 as pq
import sys
from PyQt5 import QtWidgets, uic, QtGui
Nx = None
Ny = None
Nxy = None
def Assigned(self):
global Nx, Ny, Nxy
Nx=call.Nx11.text()
Ny=call.Ny11.text()
Nxy=call.Nxy11.text()
Mx=call.Mx11.text()
My=call.My11.text()
Mxy=call.Mxy11.text()
print(Nx)
print(Ny)
print(Nxy)
app=QtWidgets.QApplication([])
call=pq.uic.loadUi("InputLoad.ui")
call.OKbutton.clicked.connect(Assigned)
call.show()
app.exec_()
This question already has answers here:
How can you easily select between PyQt or PySide at runtime?
(3 answers)
Closed 8 years ago.
I'd like to use either PyQt4 or PySide for imports, whichever is installed. For some reason though I can't do this:
from PyQt4 import QtGui
from QtGui import QApplication
Instead of the last line, I have to do this, I'm not sure why:
from PyQt4.QtGui import QApplication
That doesn't bother me too much, but it makes it very frustrating importing multiple things using whichever library is installed:
try:
from PyQt4 import QtGui, QtWebKit, QtCore
from PyQt4.QtGui import QApplication, QMainWindow, QFrame, QAction, ...
...
except ImportError:
from PySide import QtGui, QtWebKit, QtCore
from PySide.QtGui import QApplication, QMainWindow, QFrame, QAction, ...
...
It gets pretty repetitive.
Also, this doesn't work, Python won't allow it:
import PyQt4 as SomeQt
from SomeQt import QtGui
So I can't find a good way to cut down on repetition between the PyQt4 and PySide sections. Is there a better way? Is there any harm in just using import *:
try:
from PyQt4 import QtGui, QtWebKit, QtCore
from PyQt4.QtGui import *
...
except ImportError:
from PySide import QtGui, QtWebKit, QtCore
from PySide.QtGui *
...
to at least cut down on the amount of repetition necessary?
I would just do following:
try:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
...
except ImportError:
from PySide.QtCore import *
from PySide.QtGui import *
...
...
QThread()
QApplication()
QWidget()
...
Wild imports are usually discouraged by Python community and best practice. The reasoning is that you are unnecessarily polluting your namespace. Me personally, I do not care for Qt, as every class name is starting with Q, e.g. QSomething. This makes it in my opinion very unlikely to collide with another class names from my or 3rd party modules.
To be safe, you can also do something like:
try:
from PyQt4 import QtCore as Qc
from PyQt4 import QtGui as Qg
...
except ImportError:
from PySide import QtCore as Qc
from PySide import QtGui as Qg
...
...
Qc.QThread()
Qc.QApplication()
Qg.QWidget()
...
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)
I would like to keep the PyQt4 window above like I do with GTK with set_keep_above(True).
Is that possible ?
Edit 20111101 : this is my code, I don't know how to force the window "above" :
#!/usr/bin/python2
# -*- coding: utf8 -*-
import os, sys, signal
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from PyQt4.QtScript import *
from PyQt4.QtNetwork import *
if os.path.exists(".forum_smileys_cache"):
pass
else:
os.mkdir(".forum_smileys_cache")
app = QApplication(sys.argv)
signal.signal(signal.SIGINT, signal.SIG_DFL)
webpage = QWebView()
webpage.setWindowTitle("forums smileys code")
manager = webpage.page().networkAccessManager()
diskCache = QNetworkDiskCache(webpage)
diskCache.setCacheDirectory(".forum_smileys_cache")
manager.setCache(diskCache)
webpage.show()
webpage.setGeometry(0,0, 300, 550)
webpage.resize(250,800)
webpage.load(QUrl("http://www.sputnick-area.net/smileys.html"))
sys.exit(app.exec_())
I use something like this:
from PyQt4 import QtGui as qt
from PyQt4 import QtCore as qc
class MainWin(qt.QMainWindow):
def setKeepAbove(self, above):
if above:
self.setWindowFlags(self.windowFlags() | qc.Qt.WindowStaysOnTopHint)
else:
self.setWindowFlags(self.windowFlags() & ~qc.Qt.WindowStaysOnTopHint)