Merge pull request #1211 from campagnola/pyside2-uic

Add support for running pyside2-uic binary to dynamically compile ui files
This commit is contained in:
Luke Campagnola 2020-06-04 01:07:39 -07:00 committed by GitHub
commit 932b9757c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 25 deletions

View File

@ -38,14 +38,15 @@ Qt Bindings Test Matrix
The following table represents the python environments we test in our CI system. Our CI system uses Ubuntu 18.04, Windows Server 2019, and macOS 10.15 base images. The following table represents the python environments we test in our CI system. Our CI system uses Ubuntu 18.04, Windows Server 2019, and macOS 10.15 base images.
| Qt-Bindings | Python 2.7 | Python 3.6 | Python 3.7 | Python 3.8 | | Qt-Bindings | Python 2.7 | Python 3.6 | Python 3.7 | Python 3.8 |
| :----------- | :----------------: | :----------------: | :----------------: | :----------------: | | :------------- | :----------------: | :----------------: | :----------------: | :----------------: |
| PyQt-4 | :white_check_mark: | :x: | :x: | :x: | | PyQt-4 | :white_check_mark: | :x: | :x: | :x: |
| PySide1 | :white_check_mark: | :x: | :x: | :x: | | PySide1 | :white_check_mark: | :x: | :x: | :x: |
| PyQt-5.9 | :x: | :white_check_mark: | :x: | :x: | | PyQt5-5.9 | :x: | :white_check_mark: | :x: | :x: |
| PySide2-5.13 | :x: | :x: | :white_check_mark: | :x: | | PySide2-5.13 | :x: | :x: | :white_check_mark: | :x: |
| PyQt-5.14 | :x: | :x: | :x: | :white_check_mark: | | PyQt5-Latest | :x: | :x: | :x: | :white_check_mark: |
| PySide2-Latest | :x: | :x: | :x: | :white_check_mark: |
* pyqtgraph has had some incompatabilities with PySide2-5.6, and we recommend you avoid those bindings if possible * pyqtgraph has had some incompatibilities with PySide2-5.6, and we recommend you avoid those bindings if possible
* on macOS with Python 2.7 and Qt4 bindings (PyQt4 or PySide) the openGL related visualizations do not work * on macOS with Python 2.7 and Qt4 bindings (PyQt4 or PySide) the openGL related visualizations do not work
Support Support

View File

@ -18,7 +18,7 @@ jobs:
python.version: '2.7' python.version: '2.7'
qt.bindings: "pyside" qt.bindings: "pyside"
install.method: "conda" install.method: "conda"
Python36-PyQt-5.9: Python36-PyQt5-5.9:
python.version: "3.6" python.version: "3.6"
qt.bindings: "pyqt" qt.bindings: "pyqt"
install.method: "conda" install.method: "conda"
@ -26,10 +26,14 @@ jobs:
python.version: "3.7" python.version: "3.7"
qt.bindings: "pyside2" qt.bindings: "pyside2"
install.method: "conda" install.method: "conda"
Python38-PyQt-Latest: Python38-PyQt5-Latest:
python.version: '3.8' python.version: '3.8'
qt.bindings: "PyQt5" qt.bindings: "PyQt5"
install.method: "pip" install.method: "pip"
Python38-PySide2-Latest:
python.version: '3.8'
qt.bindings: "PySide2"
install.method: "pip"
steps: steps:
- task: DownloadPipelineArtifact@2 - task: DownloadPipelineArtifact@2

View File

@ -13,7 +13,7 @@ import numpy as np
import pyqtgraph as pg import pyqtgraph as pg
#QtGui.QApplication.setGraphicsSystem('raster') #QtGui.QApplication.setGraphicsSystem('raster')
app = QtGui.QApplication([]) app = pg.mkQApp()
mw = QtGui.QMainWindow() mw = QtGui.QMainWindow()
mw.setWindowTitle('pyqtgraph example: PlotWidget') mw.setWindowTitle('pyqtgraph example: PlotWidget')
mw.resize(800,800) mw.resize(800,800)

View File

@ -150,7 +150,12 @@ conditionalExamples = {
) )
} }
@pytest.mark.skipif(Qt.QT_LIB == "PySide2" and "Qt.QtVersion.startswith('5.14')", reason="new PySide2 doesn't have loadUi functionality") @pytest.mark.skipif(
Qt.QT_LIB == "PySide2"
and tuple(map(int, Qt.PySide2.__version__.split("."))) >= (5, 14)
and tuple(map(int, Qt.PySide2.__version__.split("."))) < (5, 14, 2, 2),
reason="new PySide2 doesn't have loadUi functionality"
)
@pytest.mark.parametrize( @pytest.mark.parametrize(
"frontend, f", "frontend, f",
[ [

View File

@ -10,7 +10,7 @@ This module exists to smooth out some of the differences between PySide and PyQt
""" """
import os, sys, re, time import os, sys, re, time, subprocess, warnings
from .python2_3 import asUnicode from .python2_3 import asUnicode
@ -105,22 +105,36 @@ def _loadUiType(uiFile):
if QT_LIB == "PYSIDE": if QT_LIB == "PYSIDE":
import pysideuic import pysideuic
else: else:
try:
import pyside2uic as pysideuic import pyside2uic as pysideuic
import xml.etree.ElementTree as xml except ImportError:
# later vserions of pyside2 have dropped pysideuic; use the uic binary instead.
pysideuic = None
# get class names from ui file
import xml.etree.ElementTree as xml
parsed = xml.parse(uiFile) parsed = xml.parse(uiFile)
widget_class = parsed.find('widget').get('class') widget_class = parsed.find('widget').get('class')
form_class = parsed.find('class').text form_class = parsed.find('class').text
with open(uiFile, 'r') as f: # convert ui file to python code
if pysideuic is None:
pyside2version = tuple(map(int, PySide2.__version__.split(".")))
if pyside2version >= (5, 14) and pyside2version < (5, 14, 2, 2):
warnings.warn('For UI compilation, it is recommended to upgrade to PySide >= 5.15')
uipy = subprocess.check_output(['pyside2-uic', uiFile])
else:
o = _StringIO() o = _StringIO()
frame = {} with open(uiFile, 'r') as f:
pysideuic.compileUi(f, o, indent=0) pysideuic.compileUi(f, o, indent=0)
pyc = compile(o.getvalue(), '<string>', 'exec') uipy = o.getvalue()
# exceute python code
pyc = compile(uipy, '<string>', 'exec')
frame = {}
exec(pyc, frame) exec(pyc, frame)
#Fetch the base_class and form class based on their type in the xml from designer # fetch the base_class and form class based on their type in the xml from designer
form_class = frame['Ui_%s'%form_class] form_class = frame['Ui_%s'%form_class]
base_class = eval('QtGui.%s'%widget_class) base_class = eval('QtGui.%s'%widget_class)

View File

@ -15,7 +15,12 @@ def test_isQObjectAlive():
@pytest.mark.skipif(pg.Qt.QT_LIB == 'PySide', reason='pysideuic does not appear to be ' @pytest.mark.skipif(pg.Qt.QT_LIB == 'PySide', reason='pysideuic does not appear to be '
'packaged with conda') 'packaged with conda')
@pytest.mark.skipif(pg.Qt.QT_LIB == "PySide2" and "pg.Qt.QtVersion.startswith('5.14')", reason="new PySide2 doesn't have loadUi functionality") @pytest.mark.skipif(
pg.Qt.QT_LIB == "PySide2"
and tuple(map(int, pg.Qt.PySide2.__version__.split("."))) >= (5, 14)
and tuple(map(int, pg.Qt.PySide2.__version__.split("."))) < (5, 14, 2, 2),
reason="new PySide2 doesn't have loadUi functionality"
)
def test_loadUiType(): def test_loadUiType():
path = os.path.dirname(__file__) path = os.path.dirname(__file__)
formClass, baseClass = pg.Qt.loadUiType(os.path.join(path, 'uictest.ui')) formClass, baseClass = pg.Qt.loadUiType(os.path.join(path, 'uictest.ui'))