2013-12-18 02:23:37 +00:00
|
|
|
"""
|
|
|
|
This module exists to smooth out some of the differences between PySide and PyQt4:
|
|
|
|
|
|
|
|
* Automatically import either PyQt4 or PySide depending on availability
|
|
|
|
* Allow to import QtCore/QtGui pyqtgraph.Qt without specifying which Qt wrapper
|
|
|
|
you want to use.
|
|
|
|
* Declare QtCore.Signal, .Slot in PyQt4
|
|
|
|
* Declare loadUiType function for Pyside
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
2012-10-03 01:23:59 +00:00
|
|
|
import sys, re
|
2012-03-02 02:55:32 +00:00
|
|
|
|
2014-02-14 09:29:33 +00:00
|
|
|
PYSIDE = 0
|
|
|
|
PYQT4 = 1
|
|
|
|
PYQT5 = 2
|
|
|
|
|
|
|
|
USE_QT_PY = None
|
|
|
|
|
2012-09-09 23:07:36 +00:00
|
|
|
## Automatically determine whether to use PyQt or PySide.
|
|
|
|
## This is done by first checking to see whether one of the libraries
|
|
|
|
## is already imported. If not, then attempt to import PyQt4, then PySide.
|
|
|
|
if 'PyQt4' in sys.modules:
|
2014-02-14 09:29:33 +00:00
|
|
|
USE_QT_PY = PYQT4
|
|
|
|
if 'PyQt5' in sys.modules:
|
|
|
|
USE_QT_PY = PYQT5
|
2012-09-09 23:07:36 +00:00
|
|
|
elif 'PySide' in sys.modules:
|
2014-02-14 09:29:33 +00:00
|
|
|
USE_QT_PY = PYSIDE
|
2012-09-09 23:07:36 +00:00
|
|
|
else:
|
|
|
|
try:
|
|
|
|
import PyQt4
|
2014-02-14 09:29:33 +00:00
|
|
|
USE_QT_PY = PYQT4
|
2012-09-09 23:07:36 +00:00
|
|
|
except ImportError:
|
|
|
|
try:
|
2014-02-14 09:29:33 +00:00
|
|
|
import PyQt5
|
|
|
|
USE_QT_PY = PYQT5
|
2012-09-09 23:07:36 +00:00
|
|
|
except ImportError:
|
2014-02-14 09:29:33 +00:00
|
|
|
try:
|
|
|
|
import PySide
|
|
|
|
USE_QT_PY = PYSIDE
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
if USE_QT_PY == None:
|
|
|
|
raise Exception("PyQtGraph requires one of PyQt4, PyQt5 or PySide; none of these packages could be imported.")
|
2012-06-29 18:39:27 +00:00
|
|
|
|
2014-02-14 09:29:33 +00:00
|
|
|
if USE_QT_PY == PYSIDE:
|
2012-06-29 18:39:27 +00:00
|
|
|
from PySide import QtGui, QtCore, QtOpenGL, QtSvg
|
2012-06-29 19:08:14 +00:00
|
|
|
import PySide
|
2012-06-29 18:39:27 +00:00
|
|
|
VERSION_INFO = 'PySide ' + PySide.__version__
|
2013-12-18 02:23:37 +00:00
|
|
|
|
|
|
|
# Make a loadUiType function like PyQt has
|
|
|
|
|
|
|
|
# Credit:
|
|
|
|
# http://stackoverflow.com/questions/4442286/python-code-genration-with-pyside-uic/14195313#14195313
|
|
|
|
|
|
|
|
def loadUiType(uiFile):
|
|
|
|
"""
|
|
|
|
Pyside "loadUiType" command like PyQt4 has one, so we have to convert the ui file to py code in-memory first and then execute it in a special frame to retrieve the form_class.
|
|
|
|
"""
|
|
|
|
import pysideuic
|
|
|
|
import xml.etree.ElementTree as xml
|
|
|
|
from io import StringIO
|
|
|
|
|
|
|
|
parsed = xml.parse(uiFile)
|
|
|
|
widget_class = parsed.find('widget').get('class')
|
|
|
|
form_class = parsed.find('class').text
|
|
|
|
|
|
|
|
with open(uiFile, 'r') as f:
|
|
|
|
o = StringIO()
|
|
|
|
frame = {}
|
|
|
|
|
|
|
|
pysideuic.compileUi(f, o, indent=0)
|
|
|
|
pyc = compile(o.getvalue(), '<string>', 'exec')
|
|
|
|
exec(pyc, frame)
|
|
|
|
|
|
|
|
#Fetch the base_class and form class based on their type in the xml from designer
|
|
|
|
form_class = frame['Ui_%s'%form_class]
|
|
|
|
base_class = eval('QtGui.%s'%widget_class)
|
|
|
|
|
|
|
|
return form_class, base_class
|
2014-02-14 09:29:33 +00:00
|
|
|
|
|
|
|
elif USE_QT_PY == PYQT4:
|
|
|
|
|
2013-12-18 02:23:37 +00:00
|
|
|
from PyQt4 import QtGui, QtCore, uic
|
2012-06-29 18:39:27 +00:00
|
|
|
try:
|
|
|
|
from PyQt4 import QtSvg
|
|
|
|
except ImportError:
|
|
|
|
pass
|
|
|
|
try:
|
|
|
|
from PyQt4 import QtOpenGL
|
|
|
|
except ImportError:
|
|
|
|
pass
|
2012-05-11 22:05:41 +00:00
|
|
|
|
2013-12-18 02:23:37 +00:00
|
|
|
|
|
|
|
loadUiType = uic.loadUiType
|
|
|
|
|
2012-03-02 04:23:33 +00:00
|
|
|
QtCore.Signal = QtCore.pyqtSignal
|
2012-06-29 18:39:27 +00:00
|
|
|
VERSION_INFO = 'PyQt4 ' + QtCore.PYQT_VERSION_STR + ' Qt ' + QtCore.QT_VERSION_STR
|
2012-10-03 01:23:59 +00:00
|
|
|
|
2014-02-14 09:29:33 +00:00
|
|
|
elif USE_QT_PY == PYQT5:
|
|
|
|
|
|
|
|
# We're using PyQt5 which has a different structure so we're going to use a shim to
|
|
|
|
# recreate the Qt4 structure for Qt5
|
|
|
|
from PyQt5 import QtGui, QtCore, QtWidgets, Qt, uic
|
|
|
|
try:
|
|
|
|
from PyQt5 import QtSvg
|
|
|
|
except ImportError:
|
|
|
|
pass
|
|
|
|
try:
|
|
|
|
from PyQt5 import QtOpenGL
|
|
|
|
except ImportError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
QtGui.QApplication = QtWidgets.QApplication
|
|
|
|
QtGui.QGraphicsScene = QtWidgets.QGraphicsScene
|
|
|
|
QtGui.QGraphicsObject = QtWidgets.QGraphicsObject
|
|
|
|
QtGui.QGraphicsWidget = QGraphicsWidget5
|
|
|
|
QtGui.QApplication.setGraphicsSystem = None
|
|
|
|
QtCore.Signal = Qt.pyqtSignal
|
|
|
|
|
|
|
|
# Import all QtWidgets objects into QtGui
|
|
|
|
for o in dir(QtWidgets):
|
|
|
|
if o.startswith('Q'):
|
|
|
|
setattr(QtGui, o, getattr(QtWidgets,o) )
|
|
|
|
|
2012-10-03 01:23:59 +00:00
|
|
|
## Make sure we have Qt >= 4.7
|
|
|
|
versionReq = [4, 7]
|
2014-02-14 09:29:33 +00:00
|
|
|
USE_PYSIDE = USE_QT_PY == PYSIDE # still needed internally elsewhere
|
|
|
|
QtVersion = PySide.QtCore.__version__ if USE_QT_PY == PYSIDE else QtCore.QT_VERSION_STR
|
2012-10-03 01:23:59 +00:00
|
|
|
m = re.match(r'(\d+)\.(\d+).*', QtVersion)
|
2012-12-05 05:25:45 +00:00
|
|
|
if m is not None and list(map(int, m.groups())) < versionReq:
|
2013-12-18 02:23:37 +00:00
|
|
|
print(list(map(int, m.groups())))
|
2012-10-06 06:23:23 +00:00
|
|
|
raise Exception('pyqtgraph requires Qt version >= %d.%d (your version is %s)' % (versionReq[0], versionReq[1], QtVersion))
|
2012-10-03 01:23:59 +00:00
|
|
|
|