Fix up Qt.py and deprecate USE_XX variables

This commit is contained in:
Luke Campagnola 2018-02-16 20:42:34 -08:00
parent 46f10f24f8
commit 82afad8366
34 changed files with 358 additions and 264 deletions

View File

@ -12,7 +12,7 @@ For testing rapid updates of ScatterPlotItem under various conditions.
import initExample
from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE, USE_PYSIDE2, USE_PYQT5
from pyqtgraph.Qt import QtGui, QtCore, QT_LIB
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
@ -20,11 +20,11 @@ from pyqtgraph.ptime import time
app = QtGui.QApplication([])
#mw = QtGui.QMainWindow()
#mw.resize(800,800)
if USE_PYSIDE:
if QT_LIB == 'PySide':
from ScatterPlotSpeedTestTemplate_pyside import Ui_Form
elif USE_PYSIDE2:
elif QT_LIB == 'PySide2':
from ScatterPlotSpeedTestTemplate_pyside2 import Ui_Form
elif USE_PYQT5:
elif QT_LIB == 'PyQt5':
from ScatterPlotSpeedTestTemplate_pyqt5 import Ui_Form
else:
from ScatterPlotSpeedTestTemplate_pyqt import Ui_Form

View File

@ -10,16 +10,16 @@ is used by the view widget
import initExample ## Add path to library (just for examples; you do not need this)
from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE, USE_PYSIDE2, USE_PYQT5
from pyqtgraph.Qt import QtGui, QtCore, QT_LIB
import numpy as np
import pyqtgraph as pg
import pyqtgraph.ptime as ptime
if USE_PYSIDE:
if QT_LIB == 'PySide':
import VideoTemplate_pyside as VideoTemplate
elif USE_PYSIDE2:
elif QT_LIB == 'PySide2':
import VideoTemplate_pyside2 as VideoTemplate
elif USE_PYQT5:
elif QT_LIB == 'PyQt5':
import VideoTemplate_pyqt5 as VideoTemplate
else:
import VideoTemplate_pyqt as VideoTemplate

View File

@ -7,16 +7,16 @@ if __name__ == "__main__" and (__package__ is None or __package__==''):
import pyqtgraph as pg
import subprocess
from pyqtgraph.python2_3 import basestring
from pyqtgraph.Qt import QtGui, USE_PYSIDE, USE_PYSIDE2, USE_PYQT5
from pyqtgraph.Qt import QtGui, QT_LIB
from .utils import buildFileList, testFile, path, examples
if USE_PYSIDE:
if QT_LIB == 'PySide':
from .exampleLoaderTemplate_pyside import Ui_Form
elif USE_PYSIDE2:
elif QT_LIB == 'PySide2':
from .exampleLoaderTemplate_pyside2 import Ui_Form
elif USE_PYQT5:
elif QT_LIB == 'PyQt5':
from .exampleLoaderTemplate_pyqt5 import Ui_Form
else:
from .exampleLoaderTemplate_pyqt import Ui_Form

View File

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'examples/designerExample.ui'
#
# Created: Fri Feb 16 20:31:04 2018
# by: pyside2-uic 2.0.0 running on PySide2 2.0.0~alpha0
#
# WARNING! All changes made in this file will be lost!
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 300)
self.gridLayout = QtWidgets.QGridLayout(Form)
self.gridLayout.setObjectName("gridLayout")
self.plotBtn = QtWidgets.QPushButton(Form)
self.plotBtn.setObjectName("plotBtn")
self.gridLayout.addWidget(self.plotBtn, 0, 0, 1, 1)
self.plot = PlotWidget(Form)
self.plot.setObjectName("plot")
self.gridLayout.addWidget(self.plot, 1, 0, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None, -1))
self.plotBtn.setText(QtWidgets.QApplication.translate("Form", "Plot!", None, -1))
from pyqtgraph import PlotWidget

View File

@ -79,6 +79,11 @@
<string>PyQt5</string>
</property>
</item>
<item>
<property name="text">
<string>PySide2</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">

View File

@ -1,14 +1,12 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'exampleLoaderTemplate.ui'
# Form implementation generated from reading ui file 'examples/exampleLoaderTemplate.ui'
#
# Created: Sat Feb 28 10:30:29 2015
# by: PyQt4 UI code generator 4.10.4
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
#from PyQt4 import QtCore, QtGui
from pyqtgraph.Qt import QtGui, QtCore
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
@ -36,7 +34,6 @@ class Ui_Form(object):
self.widget = QtGui.QWidget(self.splitter)
self.widget.setObjectName(_fromUtf8("widget"))
self.gridLayout = QtGui.QGridLayout(self.widget)
self.gridLayout.setMargin(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.exampleTree = QtGui.QTreeWidget(self.widget)
self.exampleTree.setObjectName(_fromUtf8("exampleTree"))
@ -56,6 +53,7 @@ class Ui_Form(object):
self.qtLibCombo.addItem(_fromUtf8(""))
self.qtLibCombo.addItem(_fromUtf8(""))
self.qtLibCombo.addItem(_fromUtf8(""))
self.qtLibCombo.addItem(_fromUtf8(""))
self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
self.label_2 = QtGui.QLabel(self.widget)
self.label_2.setObjectName(_fromUtf8("label_2"))
@ -69,7 +67,6 @@ class Ui_Form(object):
self.widget1 = QtGui.QWidget(self.splitter)
self.widget1.setObjectName(_fromUtf8("widget1"))
self.verticalLayout = QtGui.QVBoxLayout(self.widget1)
self.verticalLayout.setMargin(0)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.loadedFileLabel = QtGui.QLabel(self.widget1)
font = QtGui.QFont()
@ -101,6 +98,7 @@ class Ui_Form(object):
self.qtLibCombo.setItemText(1, _translate("Form", "PyQt4", None))
self.qtLibCombo.setItemText(2, _translate("Form", "PySide", None))
self.qtLibCombo.setItemText(3, _translate("Form", "PyQt5", None))
self.qtLibCombo.setItemText(4, _translate("Form", "PySide2", None))
self.label_2.setText(_translate("Form", "Graphics System:", None))
self.label.setText(_translate("Form", "Qt Library:", None))
self.loadBtn.setText(_translate("Form", "Run Example", None))

View File

@ -1,9 +1,8 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'exampleLoaderTemplate.ui'
# Form implementation generated from reading ui file 'examples/exampleLoaderTemplate.ui'
#
# Created: Sat Feb 28 10:28:50 2015
# by: PyQt5 UI code generator 5.2.1
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!
@ -41,6 +40,7 @@ class Ui_Form(object):
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
@ -87,6 +87,7 @@ class Ui_Form(object):
self.qtLibCombo.setItemText(1, _translate("Form", "PyQt4"))
self.qtLibCombo.setItemText(2, _translate("Form", "PySide"))
self.qtLibCombo.setItemText(3, _translate("Form", "PyQt5"))
self.qtLibCombo.setItemText(4, _translate("Form", "PySide2"))
self.label_2.setText(_translate("Form", "Graphics System:"))
self.label.setText(_translate("Form", "Qt Library:"))
self.loadBtn.setText(_translate("Form", "Run Example"))

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'exampleLoaderTemplate.ui'
# Form implementation generated from reading ui file 'examples/exampleLoaderTemplate.ui'
#
# Created: Sat Feb 28 10:31:57 2015
# by: pyside-uic 0.2.15 running on PySide 1.2.1
# Created: Fri Feb 16 20:29:46 2018
# by: pyside-uic 0.2.15 running on PySide 1.2.4
#
# WARNING! All changes made in this file will be lost!
@ -41,6 +41,7 @@ class Ui_Form(object):
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
self.label_2 = QtGui.QLabel(self.widget)
self.label_2.setObjectName("label_2")
@ -86,6 +87,7 @@ class Ui_Form(object):
self.qtLibCombo.setItemText(1, QtGui.QApplication.translate("Form", "PyQt4", None, QtGui.QApplication.UnicodeUTF8))
self.qtLibCombo.setItemText(2, QtGui.QApplication.translate("Form", "PySide", None, QtGui.QApplication.UnicodeUTF8))
self.qtLibCombo.setItemText(3, QtGui.QApplication.translate("Form", "PyQt5", None, QtGui.QApplication.UnicodeUTF8))
self.qtLibCombo.setItemText(4, QtGui.QApplication.translate("Form", "PySide2", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("Form", "Graphics System:", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("Form", "Qt Library:", None, QtGui.QApplication.UnicodeUTF8))
self.loadBtn.setText(QtGui.QApplication.translate("Form", "Run Example", None, QtGui.QApplication.UnicodeUTF8))

View File

@ -1,92 +1,94 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'exampleLoaderTemplate.ui'
#
# Created: Sun Sep 18 19:20:44 2016
# by: pyside2-uic running on PySide2 2.0.0~alpha0
#
# WARNING! All changes made in this file will be lost!
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(846, 552)
self.gridLayout_2 = QtWidgets.QGridLayout(Form)
self.gridLayout_2.setObjectName("gridLayout_2")
self.splitter = QtWidgets.QSplitter(Form)
self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter")
self.widget = QtWidgets.QWidget(self.splitter)
self.widget.setObjectName("widget")
self.gridLayout = QtWidgets.QGridLayout(self.widget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.exampleTree = QtWidgets.QTreeWidget(self.widget)
self.exampleTree.setObjectName("exampleTree")
self.exampleTree.headerItem().setText(0, "1")
self.exampleTree.header().setVisible(False)
self.gridLayout.addWidget(self.exampleTree, 0, 0, 1, 2)
self.graphicsSystemCombo = QtWidgets.QComboBox(self.widget)
self.graphicsSystemCombo.setObjectName("graphicsSystemCombo")
self.graphicsSystemCombo.addItem("")
self.graphicsSystemCombo.addItem("")
self.graphicsSystemCombo.addItem("")
self.graphicsSystemCombo.addItem("")
self.gridLayout.addWidget(self.graphicsSystemCombo, 2, 1, 1, 1)
self.qtLibCombo = QtWidgets.QComboBox(self.widget)
self.qtLibCombo.setObjectName("qtLibCombo")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
self.loadBtn = QtWidgets.QPushButton(self.widget)
self.loadBtn.setObjectName("loadBtn")
self.gridLayout.addWidget(self.loadBtn, 3, 1, 1, 1)
self.widget1 = QtWidgets.QWidget(self.splitter)
self.widget1.setObjectName("widget1")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget1)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.loadedFileLabel = QtWidgets.QLabel(self.widget1)
font = QtGui.QFont()
font.setWeight(75)
font.setBold(True)
self.loadedFileLabel.setFont(font)
self.loadedFileLabel.setText("")
self.loadedFileLabel.setAlignment(QtCore.Qt.AlignCenter)
self.loadedFileLabel.setObjectName("loadedFileLabel")
self.verticalLayout.addWidget(self.loadedFileLabel)
self.codeView = QtWidgets.QPlainTextEdit(self.widget1)
font = QtGui.QFont()
font.setFamily("FreeMono")
self.codeView.setFont(font)
self.codeView.setObjectName("codeView")
self.verticalLayout.addWidget(self.codeView)
self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None, -1))
self.graphicsSystemCombo.setItemText(0, QtWidgets.QApplication.translate("Form", "default", None, -1))
self.graphicsSystemCombo.setItemText(1, QtWidgets.QApplication.translate("Form", "native", None, -1))
self.graphicsSystemCombo.setItemText(2, QtWidgets.QApplication.translate("Form", "raster", None, -1))
self.graphicsSystemCombo.setItemText(3, QtWidgets.QApplication.translate("Form", "opengl", None, -1))
self.qtLibCombo.setItemText(0, QtWidgets.QApplication.translate("Form", "default", None, -1))
self.qtLibCombo.setItemText(1, QtWidgets.QApplication.translate("Form", "PyQt4", None, -1))
self.qtLibCombo.setItemText(2, QtWidgets.QApplication.translate("Form", "PySide", None, -1))
self.qtLibCombo.setItemText(3, QtWidgets.QApplication.translate("Form", "PyQt5", None, -1))
self.label_2.setText(QtWidgets.QApplication.translate("Form", "Graphics System:", None, -1))
self.label.setText(QtWidgets.QApplication.translate("Form", "Qt Library:", None, -1))
self.loadBtn.setText(QtWidgets.QApplication.translate("Form", "Run Example", None, -1))
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'examples/exampleLoaderTemplate.ui'
#
# Created: Fri Feb 16 20:30:37 2018
# by: pyside2-uic 2.0.0 running on PySide2 2.0.0~alpha0
#
# WARNING! All changes made in this file will be lost!
from PySide2 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(846, 552)
self.gridLayout_2 = QtWidgets.QGridLayout(Form)
self.gridLayout_2.setObjectName("gridLayout_2")
self.splitter = QtWidgets.QSplitter(Form)
self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter")
self.widget = QtWidgets.QWidget(self.splitter)
self.widget.setObjectName("widget")
self.gridLayout = QtWidgets.QGridLayout(self.widget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.exampleTree = QtWidgets.QTreeWidget(self.widget)
self.exampleTree.setObjectName("exampleTree")
self.exampleTree.headerItem().setText(0, "1")
self.exampleTree.header().setVisible(False)
self.gridLayout.addWidget(self.exampleTree, 0, 0, 1, 2)
self.graphicsSystemCombo = QtWidgets.QComboBox(self.widget)
self.graphicsSystemCombo.setObjectName("graphicsSystemCombo")
self.graphicsSystemCombo.addItem("")
self.graphicsSystemCombo.addItem("")
self.graphicsSystemCombo.addItem("")
self.graphicsSystemCombo.addItem("")
self.gridLayout.addWidget(self.graphicsSystemCombo, 2, 1, 1, 1)
self.qtLibCombo = QtWidgets.QComboBox(self.widget)
self.qtLibCombo.setObjectName("qtLibCombo")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.qtLibCombo.addItem("")
self.gridLayout.addWidget(self.qtLibCombo, 1, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(self.widget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.label = QtWidgets.QLabel(self.widget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 1, 0, 1, 1)
self.loadBtn = QtWidgets.QPushButton(self.widget)
self.loadBtn.setObjectName("loadBtn")
self.gridLayout.addWidget(self.loadBtn, 3, 1, 1, 1)
self.widget1 = QtWidgets.QWidget(self.splitter)
self.widget1.setObjectName("widget1")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget1)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.loadedFileLabel = QtWidgets.QLabel(self.widget1)
font = QtGui.QFont()
font.setWeight(75)
font.setBold(True)
self.loadedFileLabel.setFont(font)
self.loadedFileLabel.setText("")
self.loadedFileLabel.setAlignment(QtCore.Qt.AlignCenter)
self.loadedFileLabel.setObjectName("loadedFileLabel")
self.verticalLayout.addWidget(self.loadedFileLabel)
self.codeView = QtWidgets.QPlainTextEdit(self.widget1)
font = QtGui.QFont()
font.setFamily("FreeMono")
self.codeView.setFont(font)
self.codeView.setObjectName("codeView")
self.verticalLayout.addWidget(self.codeView)
self.gridLayout_2.addWidget(self.splitter, 0, 0, 1, 1)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtWidgets.QApplication.translate("Form", "Form", None, -1))
self.graphicsSystemCombo.setItemText(0, QtWidgets.QApplication.translate("Form", "default", None, -1))
self.graphicsSystemCombo.setItemText(1, QtWidgets.QApplication.translate("Form", "native", None, -1))
self.graphicsSystemCombo.setItemText(2, QtWidgets.QApplication.translate("Form", "raster", None, -1))
self.graphicsSystemCombo.setItemText(3, QtWidgets.QApplication.translate("Form", "opengl", None, -1))
self.qtLibCombo.setItemText(0, QtWidgets.QApplication.translate("Form", "default", None, -1))
self.qtLibCombo.setItemText(1, QtWidgets.QApplication.translate("Form", "PyQt4", None, -1))
self.qtLibCombo.setItemText(2, QtWidgets.QApplication.translate("Form", "PySide", None, -1))
self.qtLibCombo.setItemText(3, QtWidgets.QApplication.translate("Form", "PyQt5", None, -1))
self.qtLibCombo.setItemText(4, QtWidgets.QApplication.translate("Form", "PySide2", None, -1))
self.label_2.setText(QtWidgets.QApplication.translate("Form", "Graphics System:", None, -1))
self.label.setText(QtWidgets.QApplication.translate("Form", "Qt Library:", None, -1))
self.loadBtn.setText(QtWidgets.QApplication.translate("Form", "Run Example", None, -1))

View File

@ -26,6 +26,8 @@ elif 'pyqt' in sys.argv:
from PyQt4 import QtGui
elif 'pyqt5' in sys.argv:
from PyQt5 import QtGui
elif 'pyside2' in sys.argv:
from PySide2 import QtGui
else:
from pyqtgraph.Qt import QtGui

View File

@ -1,14 +1,14 @@
from ..Qt import QtCore, QtGui, USE_PYSIDE, USE_PYSIDE2, USE_PYQT5
from ..Qt import QtCore, QtGui, QT_LIB
from .. import exporters as exporters
from .. import functions as fn
from ..graphicsItems.ViewBox import ViewBox
from ..graphicsItems.PlotItem import PlotItem
if USE_PYSIDE:
if QT_LIB == 'PySide':
from . import exportDialogTemplate_pyside as exportDialogTemplate
elif USE_PYSIDE2:
elif QT_LIB == 'PySide2':
from . import exportDialogTemplate_pyside2 as exportDialogTemplate
elif USE_PYQT5:
elif QT_LIB == 'PyQt5':
from . import exportDialogTemplate_pyqt5 as exportDialogTemplate
else:
from . import exportDialogTemplate_pyqt as exportDialogTemplate

View File

@ -14,17 +14,18 @@ import os, sys, re, time
from .python2_3 import asUnicode
PYSIDE = 'PySide'
PYSIDE2 = 'PySide2'
PYQT4 = 'PyQt4'
PYQT5 = 'PyQt5'
QT_LIB = os.getenv('PYQTGRAPH_QT_LIB')
## Automatically determine whether to use PyQt or PySide (unless specified by
## Automatically determine which Qt package to use (unless specified by
## environment variable).
## 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 QT_LIB is None:
libOrder = [PYQT4, PYSIDE, PYQT5]
libOrder = [PYQT4, PYSIDE, PYQT5, PYSIDE2]
for lib in libOrder:
if lib in sys.modules:
@ -41,7 +42,7 @@ if QT_LIB is None:
pass
if QT_LIB is None:
raise Exception("PyQtGraph requires one of PyQt4, PyQt5 or PySide; none of these packages could be imported.")
raise Exception("PyQtGraph requires one of PyQt4, PyQt5, PySide or PySide2; none of these packages could be imported.")
class FailedImport(object):
@ -54,6 +55,74 @@ class FailedImport(object):
raise self.err
def _isQObjectAlive(obj):
"""An approximation of PyQt's isQObjectAlive().
"""
try:
if hasattr(obj, 'parent'):
obj.parent()
elif hasattr(obj, 'parentItem'):
obj.parentItem()
else:
raise Exception("Cannot determine whether Qt object %s is still alive." % obj)
except RuntimeError:
return False
else:
return True
# Make a loadUiType function like PyQt has
# Credit:
# http://stackoverflow.com/questions/4442286/python-code-genration-with-pyside-uic/14195313#14195313
class _StringIO(object):
"""Alternative to built-in StringIO needed to circumvent unicode/ascii issues"""
def __init__(self):
self.data = []
def write(self, data):
self.data.append(data)
def getvalue(self):
return ''.join(map(asUnicode, self.data)).encode('utf8')
def _loadUiType(uiFile):
"""
PySide lacks a "loadUiType" command like PyQt4's, 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.
from stackoverflow: http://stackoverflow.com/a/14195313/3781327
seems like this might also be a legitimate solution, but I'm not sure
how to make PyQt4 and pyside look the same...
http://stackoverflow.com/a/8717832
"""
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
if QT_LIB == PYSIDE:
from PySide import QtGui, QtCore
@ -68,89 +137,20 @@ if QT_LIB == PYSIDE:
try:
from PySide import QtTest
if not hasattr(QtTest.QTest, 'qWait'):
@staticmethod
def qWait(msec):
start = time.time()
QtGui.QApplication.processEvents()
while time.time() < start + msec * 0.001:
QtGui.QApplication.processEvents()
QtTest.QTest.qWait = qWait
except ImportError as err:
QtTest = FailedImport(err)
import PySide
try:
from PySide import shiboken
isQObjectAlive = shiboken.isValid
except ImportError:
def isQObjectAlive(obj):
try:
if hasattr(obj, 'parent'):
obj.parent()
elif hasattr(obj, 'parentItem'):
obj.parentItem()
else:
raise Exception("Cannot determine whether Qt object %s is still alive." % obj)
except RuntimeError:
return False
else:
return True
# use approximate version
isQObjectAlive = _isQObjectAlive
VERSION_INFO = 'PySide ' + PySide.__version__
import PySide
VERSION_INFO = 'PySide ' + PySide.__version__ + ' Qt ' + QtCore.__version__
# Make a loadUiType function like PyQt has
# Credit:
# http://stackoverflow.com/questions/4442286/python-code-genration-with-pyside-uic/14195313#14195313
class StringIO(object):
"""Alternative to built-in StringIO needed to circumvent unicode/ascii issues"""
def __init__(self):
self.data = []
def write(self, data):
self.data.append(data)
def getvalue(self):
return ''.join(map(asUnicode, self.data)).encode('utf8')
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.
from stackoverflow: http://stackoverflow.com/a/14195313/3781327
seems like this might also be a legitimate solution, but I'm not sure
how to make PyQt4 and pyside look the same...
http://stackoverflow.com/a/8717832
"""
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
elif QT_LIB == PYQT4:
from PyQt4 import QtGui, QtCore, uic
try:
from PyQt4 import QtSvg
@ -168,7 +168,6 @@ elif QT_LIB == PYQT4:
VERSION_INFO = 'PyQt4 ' + QtCore.PYQT_VERSION_STR + ' Qt ' + QtCore.QT_VERSION_STR
elif QT_LIB == 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, uic
@ -198,8 +197,39 @@ elif QT_LIB == PYQT5:
except ImportError as err:
QtTest = FailedImport(err)
# Re-implement deprecated APIs
VERSION_INFO = 'PyQt5 ' + QtCore.PYQT_VERSION_STR + ' Qt ' + QtCore.QT_VERSION_STR
elif QT_LIB == PYSIDE2:
from PySide2 import QtGui, QtCore, QtWidgets
try:
from PySide2 import QtSvg
except ImportError as err:
QtSvg = FailedImport(err)
try:
from PySide2 import QtOpenGL
except ImportError as err:
QtOpenGL = FailedImport(err)
try:
from PySide2 import QtTest
QtTest.QTest.qWaitForWindowShown = QtTest.QTest.qWaitForWindowExposed
except ImportError as err:
QtTest = FailedImport(err)
isQObjectAlive = _isQObjectAlive
import PySide2
VERSION_INFO = 'PySide2 ' + PySide2.__version__ + ' Qt ' + QtCore.__version__
else:
raise ValueError("Invalid Qt lib '%s'" % QT_LIB)
# common to PyQt5 and PySide2
if QT_LIB in [PYQT5, PYSIDE2]:
# We're using Qt5 which has a different structure so we're going to use a shim to
# recreate the Qt4 structure
__QGraphicsItem_scale = QtWidgets.QGraphicsItem.scale
def scale(self, *args):
@ -246,28 +276,45 @@ elif QT_LIB == PYQT5:
if o.startswith('Q'):
setattr(QtGui, o, getattr(QtWidgets,o) )
VERSION_INFO = 'PyQt5 ' + QtCore.PYQT_VERSION_STR + ' Qt ' + QtCore.QT_VERSION_STR
else:
raise ValueError("Invalid Qt lib '%s'" % QT_LIB)
# Common to PySide and PySide2
if QT_LIB in [PYSIDE, PYSIDE2]:
QtVersion = QtCore.__version__
loadUiType = _loadUiType
# PySide does not implement qWait
if not isinstance(QtTest, FailedImport):
if not hasattr(QtTest.QTest, 'qWait'):
@staticmethod
def qWait(msec):
start = time.time()
QtGui.QApplication.processEvents()
while time.time() < start + msec * 0.001:
QtGui.QApplication.processEvents()
QtTest.QTest.qWait = qWait
# Common to PyQt4 and 5
if QT_LIB.startswith('PyQt'):
if QT_LIB in [PYQT4, PYQT5]:
QtVersion = QtCore.QT_VERSION_STR
import sip
def isQObjectAlive(obj):
return not sip.isdeleted(obj)
loadUiType = uic.loadUiType
QtCore.Signal = QtCore.pyqtSignal
## Make sure we have Qt >= 4.7
versionReq = [4, 7]
# USE_XXX variables are deprecated
USE_PYSIDE = QT_LIB == PYSIDE
USE_PYQT4 = QT_LIB == PYQT4
USE_PYQT5 = QT_LIB == PYQT5
QtVersion = PySide.QtCore.__version__ if QT_LIB == PYSIDE else QtCore.QT_VERSION_STR
## Make sure we have Qt >= 4.7
versionReq = [4, 7]
m = re.match(r'(\d+)\.(\d+).*', QtVersion)
if m is not None and list(map(int, m.groups())) < versionReq:
print(list(map(int, m.groups())))

View File

@ -5,7 +5,7 @@ Copyright 2010 Luke Campagnola
Distributed under MIT/X11 license. See license.txt for more infomation.
"""
from .Qt import QtGui, QtCore, USE_PYSIDE
from .Qt import QtGui, QtCore, QT_LIB
import numpy as np
class Vector(QtGui.QVector3D):
@ -36,7 +36,7 @@ class Vector(QtGui.QVector3D):
def __add__(self, b):
# workaround for pyside bug. see https://bugs.launchpad.net/pyqtgraph/+bug/1223173
if USE_PYSIDE and isinstance(b, QtGui.QVector3D):
if QT_LIB == 'PySide' and isinstance(b, QtGui.QVector3D):
b = Vector(b)
return QtGui.QVector3D.__add__(self, b)

View File

@ -8,7 +8,7 @@ This class addresses the problem of having to save and restore the state
of a large group of widgets.
"""
from .Qt import QtCore, QtGui, USE_PYQT5
from .Qt import QtCore, QtGui, QT_LIB
import weakref, inspect
from .python2_3 import asUnicode
@ -218,7 +218,7 @@ class WidgetGroup(QtCore.QObject):
v1 = self.cache[n]
v2 = self.readWidget(w)
if v1 != v2:
if not USE_PYQT5:
if QT_LIB != 'PyQt5':
# Old signal kept for backward compatibility.
self.emit(QtCore.SIGNAL('changed'), self.widgetList[w], v2)
self.sigChanged.emit(self.widgetList[w], v2)

View File

@ -1,15 +1,15 @@
import sys, re, os, time, traceback, subprocess
import pickle
from ..Qt import QtCore, QtGui, USE_PYSIDE, USE_PYSIDE2, USE_PYQT5
from ..Qt import QtCore, QtGui, QT_LIB
from ..python2_3 import basestring
from .. import exceptionHandling as exceptionHandling
from .. import getConfigOption
if USE_PYSIDE:
if QT_LIB == 'PySide':
from . import template_pyside as template
elif USE_PYSIDE2:
elif QT_LIB == 'PySide2':
from . import template_pyside2 as template
elif USE_PYQT5:
elif QT_LIB == 'PyQt5':
from . import template_pyqt5 as template
else:
from . import template_pyqt as template

View File

@ -1,6 +1,6 @@
from .Exporter import Exporter
from ..parametertree import Parameter
from ..Qt import QtGui, QtCore, QtSvg, USE_PYSIDE
from ..Qt import QtGui, QtCore, QtSvg, QT_LIB
from .. import functions as fn
import numpy as np
@ -47,7 +47,7 @@ class ImageExporter(Exporter):
def export(self, fileName=None, toBytes=False, copy=False):
if fileName is None and not toBytes and not copy:
if USE_PYSIDE:
if QT_LIB in ['PySide', 'PySide2']:
filter = ["*."+str(f) for f in QtGui.QImageWriter.supportedImageFormats()]
else:
filter = ["*."+bytes(f).decode('utf-8') for f in QtGui.QImageWriter.supportedImageFormats()]

View File

@ -1,7 +1,7 @@
from .Exporter import Exporter
from ..python2_3 import asUnicode
from ..parametertree import Parameter
from ..Qt import QtGui, QtCore, QtSvg, USE_PYSIDE
from ..Qt import QtGui, QtCore, QtSvg, QT_LIB
from .. import debug
from .. import functions as fn
import re
@ -186,7 +186,7 @@ def _generateItemSvg(item, nodes=None, root=None):
#if hasattr(item, 'setExportMode'):
#item.setExportMode(False)
if USE_PYSIDE:
if QT_LIB in ['PySide', 'PySide2']:
xmlStr = str(arr)
else:
xmlStr = bytes(arr).decode('utf-8')

View File

@ -1,18 +1,18 @@
# -*- coding: utf-8 -*-
from ..Qt import QtCore, QtGui, USE_PYSIDE, USE_PYSIDE2, USE_PYQT5
from ..Qt import QtCore, QtGui, QT_LIB
from .Node import *
from ..pgcollections import OrderedDict
from ..widgets.TreeWidget import *
from .. import FileDialog, DataTreeWidget
## pyside and pyqt use incompatible ui files.
if USE_PYSIDE:
if QT_LIB == 'PySide':
from . import FlowchartTemplate_pyside as FlowchartTemplate
from . import FlowchartCtrlTemplate_pyside as FlowchartCtrlTemplate
elif USE_PYSIDE2:
elif QT_LIB == 'PySide2':
from . import FlowchartTemplate_pyside2 as FlowchartTemplate
from . import FlowchartCtrlTemplate_pyside2 as FlowchartCtrlTemplate
elif USE_PYQT5:
elif QT_LIB == 'PyQt5':
from . import FlowchartTemplate_pyqt5 as FlowchartTemplate
from . import FlowchartCtrlTemplate_pyqt5 as FlowchartCtrlTemplate
else:
@ -622,7 +622,7 @@ class FlowchartCtrlWidget(QtGui.QWidget):
self.cwWin.resize(1000,800)
h = self.ui.ctrlList.header()
if not USE_PYQT5:
if QT_LIB in ['PyQt4', 'PySide']:
h.setResizeMode(0, h.Stretch)
else:
h.setSectionResizeMode(0, h.Stretch)

View File

@ -12,7 +12,7 @@ import decimal, re
import ctypes
import sys, struct
from .python2_3 import asUnicode, basestring
from .Qt import QtGui, QtCore, USE_PYSIDE, USE_PYSIDE2
from .Qt import QtGui, QtCore, QT_LIB
from . import getConfigOption, setConfigOptions
from . import debug
from .metaarray import MetaArray
@ -1219,7 +1219,7 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True):
if copy is True and copied is False:
imgData = imgData.copy()
if USE_PYSIDE or USE_PYSIDE2:
if QT_LIB in ['PySide', 'PySide2']:
ch = ctypes.c_char.from_buffer(imgData, 0)
# Bug in PySide + Python 3 causes refcount for image data to be improperly
@ -1277,7 +1277,7 @@ def imageToArray(img, copy=False, transpose=True):
"""
fmt = img.format()
ptr = img.bits()
if USE_PYSIDE or USE_PYSIDE2:
if QT_LIB in ['PySide', 'PySide2']:
arr = np.frombuffer(ptr, dtype=np.ubyte)
else:
ptr.setsize(img.byteCount())

View File

@ -1,4 +1,4 @@
from ..Qt import QtGui, USE_PYQT5, USE_PYQT4, USE_PYSIDE, USE_PYSIDE2
from ..Qt import QtGui
from .. import functions as fn
from .PlotDataItem import PlotDataItem
from .PlotCurveItem import PlotCurveItem

View File

@ -1,5 +1,5 @@
from ..Qt import QtGui, QtCore, USE_PYSIDE, USE_PYSIDE2
if not USE_PYSIDE and not USE_PYSIDE2:
from ..Qt import QtGui, QtCore, QT_LIB
if QT_LIB in ['PyQt4', 'PyQt5']:
import sip
from .GraphicsItem import GraphicsItem
@ -33,7 +33,7 @@ class GraphicsObject(GraphicsItem, QtGui.QGraphicsObject):
## workaround for pyqt bug:
## http://www.riverbankcomputing.com/pipermail/pyqt/2012-August/031818.html
if not USE_PYSIDE and not USE_PYSIDE2 and change == self.ItemParentChange and isinstance(ret, QtGui.QGraphicsItem):
if QT_LIB in ['PyQt4', 'PyQt5'] and change == self.ItemParentChange and isinstance(ret, QtGui.QGraphicsItem):
ret = sip.cast(ret, QtGui.QGraphicsItem)
return ret

View File

@ -5,7 +5,7 @@ except ImportError:
imap = map
import numpy as np
import weakref
from ..Qt import QtGui, QtCore, USE_PYSIDE, USE_PYSIDE2, USE_PYQT5
from ..Qt import QtGui, QtCore, QT_LIB
from ..Point import Point
from .. import functions as fn
from .GraphicsItem import GraphicsItem
@ -773,10 +773,10 @@ class ScatterPlotItem(GraphicsObject):
self.data['targetRect'][updateMask] = list(imap(QtCore.QRectF, updatePts[0,:], updatePts[1,:], width, width))
data = self.data[viewMask]
if USE_PYSIDE or USE_PYSIDE2 or USE_PYQT5:
list(imap(p.drawPixmap, data['targetRect'], repeat(atlas), data['sourceRect']))
else:
if QT_LIB == 'PyQt4':
p.drawPixmapFragments(data['targetRect'].tolist(), data['sourceRect'].tolist(), atlas)
else:
list(imap(p.drawPixmap, data['targetRect'], repeat(atlas), data['sourceRect']))
else:
# render each symbol individually
p.setRenderHint(p.Antialiasing, aa)

View File

@ -1,7 +1,7 @@
from ..Qt import QtGui, QtCore, USE_PYSIDE, USE_PYSIDE2
from ..Qt import QtGui, QtCore, QT_LIB
import weakref
from .GraphicsObject import GraphicsObject
if not USE_PYSIDE and not USE_PYSIDE2:
if QT_LIB in ['PyQt4', 'PyQt5']:
import sip
__all__ = ['UIGraphicsItem']
@ -49,7 +49,7 @@ class UIGraphicsItem(GraphicsObject):
## workaround for pyqt bug:
## http://www.riverbankcomputing.com/pipermail/pyqt/2012-August/031818.html
if not USE_PYSIDE and not USE_PYSIDE2 and change == self.ItemParentChange and isinstance(ret, QtGui.QGraphicsItem):
if QT_LIB in ['PyQt4', 'PyQt5'] and change == self.ItemParentChange and isinstance(ret, QtGui.QGraphicsItem):
ret = sip.cast(ret, QtGui.QGraphicsItem)
if change == self.ItemScenePositionHasChanged:

View File

@ -134,7 +134,7 @@ def test_ImageItem_axisorder():
pg.setConfigOptions(imageAxisOrder=origMode)
@pytest.mark.skipif(pg.Qt.USE_PYSIDE, reason="pyside does not have qWait")
@pytest.mark.skipif(pg.Qt.QT_LIB=='PySide', reason="pyside does not have qWait")
def test_dividebyzero():
import pyqtgraph as pg
im = pg.image(pg.np.random.normal(size=(100,100)))

View File

@ -15,12 +15,12 @@ Widget used for displaying 2D or 3D data. Features:
import os, sys
import numpy as np
from ..Qt import QtCore, QtGui, USE_PYSIDE, USE_PYSIDE2, USE_PYQT5
if USE_PYSIDE:
from ..Qt import QtCore, QtGui, QT_LIB
if QT_LIB == 'PySide':
from .ImageViewTemplate_pyside import *
elif USE_PYSIDE2:
elif QT_LIB == 'PySide2':
from .ImageViewTemplate_pyside2 import *
elif USE_PYQT5:
elif QT_LIB == 'PyQt5':
from .ImageViewTemplate_pyqt5 import *
else:
from .ImageViewTemplate_pyqt import *

View File

@ -29,9 +29,13 @@ if __name__ == '__main__':
for k,v in pyqtapis.items():
sip.setapi(k, v)
if opts.pop('pyside', False):
qt_lib = opts.pop('qt_lib', None)
if qt_lib == 'PySide':
import PySide
elif qt_lib == 'PySide2':
import PySide2
elif qt_lib == 'PyQt5':
import PyQt5
targetStr = opts.pop('targetStr')
try:

View File

@ -6,7 +6,7 @@ except ImportError:
import pickle
from .remoteproxy import RemoteEventHandler, ClosedError, NoResultError, LocalObjectProxy, ObjectProxy
from ..Qt import USE_PYSIDE
from ..Qt import QT_LIB
from ..util import cprint # color printing for debugging
@ -131,7 +131,7 @@ class Process(RemoteEventHandler):
ppid=pid,
targetStr=targetStr,
path=sysPath,
pyside=USE_PYSIDE,
qt_lib=QT_LIB,
debug=procDebug,
pyqtapis=pyqtapis,
)

View File

@ -1,4 +1,4 @@
from ..Qt import QtCore, QtGui, QtOpenGL, USE_PYQT5
from ..Qt import QtCore, QtGui, QtOpenGL, QT_LIB
from OpenGL.GL import *
import OpenGL.GL.framebufferobjects as glfbo
import numpy as np
@ -325,7 +325,7 @@ class GLViewWidget(QtOpenGL.QGLWidget):
def wheelEvent(self, ev):
delta = 0
if not USE_PYQT5:
if QT_LIB in ['PyQt4', 'PySide']:
delta = ev.delta()
else:
delta = ev.angleDelta().x()

View File

@ -13,8 +13,8 @@ def test_isQObjectAlive():
gc.collect()
assert not pg.Qt.isQObjectAlive(o2)
@pytest.mark.skipif(pg.Qt.USE_PYSIDE, reason='pysideuic does not appear to be '
'packaged with conda')
@pytest.mark.skipif(pg.Qt.QT_LIB == 'PySide', reason='pysideuic does not appear to be '
'packaged with conda')
def test_loadUiType():
path = os.path.dirname(__file__)
formClass, baseClass = pg.Qt.loadUiType(os.path.join(path, 'uictest.ui'))

View File

@ -40,7 +40,7 @@ def mkrefs(*objs):
return map(weakref.ref, allObjs.values())
@pytest.mark.skipif(six.PY3 or pg.Qt.USE_PYSIDE, reason=skipreason)
@pytest.mark.skipif(six.PY3 or pg.Qt.QT_LIB == 'PySide', reason=skipreason)
def test_PlotWidget():
def mkobjs(*args, **kwds):
w = pg.PlotWidget(*args, **kwds)
@ -58,7 +58,7 @@ def test_PlotWidget():
for i in range(5):
assert_alldead(mkobjs())
@pytest.mark.skipif(six.PY3 or pg.Qt.USE_PYSIDE, reason=skipreason)
@pytest.mark.skipif(six.PY3 or pg.Qt.QT_LIB == 'PySide', reason=skipreason)
def test_ImageView():
def mkobjs():
iv = pg.ImageView()
@ -71,7 +71,7 @@ def test_ImageView():
assert_alldead(mkobjs())
@pytest.mark.skipif(six.PY3 or pg.Qt.USE_PYSIDE, reason=skipreason)
@pytest.mark.skipif(six.PY3 or pg.Qt.QT_LIB == 'PySide', reason=skipreason)
def test_GraphicsWindow():
def mkobjs():
w = pg.GraphicsWindow()

View File

@ -5,7 +5,7 @@ Copyright 2010 Luke Campagnola
Distributed under MIT/X11 license. See license.txt for more infomation.
"""
from ..Qt import QtCore, QtGui, USE_PYSIDE
from ..Qt import QtCore, QtGui, QT_LIB
try:
from ..Qt import QtOpenGL
@ -115,7 +115,7 @@ class GraphicsView(QtGui.QGraphicsView):
## Workaround for PySide crash
## This ensures that the scene will outlive the view.
if USE_PYSIDE:
if QT_LIB == 'PySide':
self.sceneObj._view_ref_workaround = self
## by default we set up a central widget with a grid layout.

View File

@ -1,8 +1,8 @@
from ..Qt import QtGui, QtCore, USE_PYSIDE, USE_PYQT5
from ..Qt import QtGui, QtCore, QT_LIB
import matplotlib
if not USE_PYQT5:
if USE_PYSIDE:
if QT_LIB != 'PyQt5':
if QT_LIB == 'PySide':
matplotlib.rcParams['backend.qt4']='PySide'
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas

View File

@ -1,5 +1,5 @@
from ..Qt import QtGui, QtCore, USE_PYSIDE, USE_PYSIDE2
if not USE_PYSIDE and not USE_PYSIDE2:
from ..Qt import QtGui, QtCore, QT_LIB
if QT_LIB in ['PyQt4', 'PyQt5']:
import sip
from .. import multiprocess as mp
from .GraphicsView import GraphicsView
@ -208,7 +208,7 @@ class Renderer(GraphicsView):
self.shm.resize(size)
## render the scene directly to shared memory
if USE_PYSIDE:
if QT_LIB in ['PySide', 'PySide2']:
ch = ctypes.c_char.from_buffer(self.shm, 0)
#ch = ctypes.c_char_p(address)
self.img = QtGui.QImage(ch, self.width(), self.height(), QtGui.QImage.Format_ARGB32)

View File

@ -10,6 +10,7 @@ import os, sys, subprocess, tempfile
pyqtuic = 'pyuic4'
pysideuic = 'pyside-uic'
pyqt5uic = 'pyuic5'
pyside2uic = 'pyside2-uic'
usage = """Compile .ui files to .py for all supported pyqt/pyside versions.
@ -49,7 +50,7 @@ for arg in args:
# rebuild all requested ui files
for ui in uifiles:
base, _ = os.path.splitext(ui)
for compiler, ext in [(pyqtuic, '_pyqt.py'), (pysideuic, '_pyside.py'), (pyqt5uic, '_pyqt5.py')]:
for compiler, ext in [(pyqtuic, '_pyqt.py'), (pysideuic, '_pyside.py'), (pyqt5uic, '_pyqt5.py'), (pyside2uic, '_pyside2.py')]:
py = base + ext
if not force and os.path.exists(py) and os.stat(ui).st_mtime <= os.stat(py).st_mtime:
print("Skipping %s; already compiled." % py)