Add almost all examples to ExampleApp (#1511)

* fix: delete generated designerExample_*.py files

designerExample.py loads designerExample.ui directly

* remove unused examples/utils.py

* add almost all examples in folder

* use mkQApp and don't set style nor palette

not needed for an example and also avoids a PyQt6 6.0 refcount bug in
app.setStyle()

* bold interesting examples

* test_examples.py needs to know about Namespace too

* Revert "remove unused examples/utils.py"

This reverts commit 2eddead459.

* categorize examples lists in utils.py
This commit is contained in:
pijyoi 2021-01-27 05:45:53 +08:00 committed by GitHub
parent 74bcd3ba87
commit 1044a7b6c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 95 additions and 227 deletions

View File

@ -9,17 +9,20 @@ import initExample ## Add path to library (just for examples; you do not need th
import sys
import time
import os
import numpy as np
from PyQt5 import QtWidgets, QtCore, uic
import pyqtgraph as pg
from pyqtgraph.Qt import QtWidgets, QtCore, loadUiType
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
BLUE = pg.mkPen('#1f77b4')
Design, _ = uic.loadUiType('DateAxisItem_QtDesigner.ui')
path = os.path.dirname(os.path.abspath(__file__))
uiFile = os.path.join(path, 'DateAxisItem_QtDesigner.ui')
Design, _ = loadUiType(uiFile)
class ExampleApp(QtWidgets.QMainWindow, Design):
def __init__(self):
@ -34,9 +37,7 @@ class ExampleApp(QtWidgets.QMainWindow, Design):
self.plotWidget.setAxisItems({'bottom': pg.DateAxisItem()})
self.plotWidget.showGrid(x=True, y=True)
app = QtWidgets.QApplication(sys.argv)
app.setStyle(QtWidgets.QStyleFactory.create('Fusion'))
app.setPalette(QtWidgets.QApplication.style().standardPalette())
app = pg.mkQApp("DateAxisItem_QtDesigner Example")
window = ExampleApp()
window.setWindowTitle('pyqtgraph example: DateAxisItem_QtDesigner')
window.show()

View File

@ -3,10 +3,11 @@ import os
import re
import sys
import subprocess
from argparse import Namespace
import pyqtgraph as pg
from pyqtgraph.python2_3 import basestring
from pyqtgraph.Qt import QtGui, QtCore, QT_LIB
from pyqtgraph.pgcollections import OrderedDict
from .utils import examples
path = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, path)
@ -16,88 +17,6 @@ import importlib
ui_template = importlib.import_module(
f'exampleLoaderTemplate_{QT_LIB.lower()}')
examples = OrderedDict([
('Command-line usage', 'CLIexample.py'),
('Basic Plotting', 'Plotting.py'),
('ImageView', 'ImageView.py'),
('ParameterTree', 'parametertree.py'),
('Crosshair / Mouse interaction', 'crosshair.py'),
('Data Slicing', 'DataSlicing.py'),
('Plot Customization', 'customPlot.py'),
('Timestamps on x axis', 'DateAxisItem.py'),
('Image Analysis', 'imageAnalysis.py'),
('ViewBox Features', 'ViewBoxFeatures.py'),
('Dock widgets', 'dockarea.py'),
('Console', 'ConsoleWidget.py'),
('Histograms', 'histogram.py'),
('Beeswarm plot', 'beeswarm.py'),
('Symbols', 'Symbols.py'),
('Auto-range', 'PlotAutoRange.py'),
('Remote Plotting', 'RemoteSpeedTest.py'),
('Scrolling plots', 'scrollingPlots.py'),
('HDF5 big data', 'hdf5.py'),
('Demos', OrderedDict([
('Optics', 'optics_demos.py'),
('Special relativity', 'relativity_demo.py'),
('Verlet chain', 'verlet_chain_demo.py'),
('Koch Fractal', 'fractal.py'),
])),
('GraphicsItems', OrderedDict([
('Scatter Plot', 'ScatterPlot.py'),
#('PlotItem', 'PlotItem.py'),
('IsocurveItem', 'isocurve.py'),
('GraphItem', 'GraphItem.py'),
('ErrorBarItem', 'ErrorBarItem.py'),
('FillBetweenItem', 'FillBetweenItem.py'),
('ImageItem - video', 'ImageItem.py'),
('ImageItem - draw', 'Draw.py'),
('Region-of-Interest', 'ROIExamples.py'),
('Bar Graph', 'BarGraphItem.py'),
('GraphicsLayout', 'GraphicsLayout.py'),
('LegendItem', 'Legend.py'),
('Text Item', 'text.py'),
('Linked Views', 'linkedViews.py'),
('Arrow', 'Arrow.py'),
('ViewBox', 'ViewBoxFeatures.py'),
('Custom Graphics', 'customGraphicsItem.py'),
('Labeled Graph', 'CustomGraphItem.py'),
])),
('Benchmarks', OrderedDict([
('Video speed test', 'VideoSpeedTest.py'),
('Line Plot update', 'PlotSpeedTest.py'),
('Scatter Plot update', 'ScatterPlotSpeedTest.py'),
('Multiple plots', 'MultiPlotSpeedTest.py'),
])),
('3D Graphics', OrderedDict([
('Volumetric', 'GLVolumeItem.py'),
('Isosurface', 'GLIsosurface.py'),
('Surface Plot', 'GLSurfacePlot.py'),
('Scatter Plot', 'GLScatterPlotItem.py'),
('Shaders', 'GLshaders.py'),
('Line Plot', 'GLLinePlotItem.py'),
('Mesh', 'GLMeshItem.py'),
('Image', 'GLImageItem.py'),
])),
('Widgets', OrderedDict([
('PlotWidget', 'PlotWidget.py'),
('SpinBox', 'SpinBox.py'),
('ConsoleWidget', 'ConsoleWidget.py'),
('Histogram / lookup table', 'HistogramLUT.py'),
('TreeWidget', 'TreeWidget.py'),
('ScatterPlotWidget', 'ScatterPlotWidget.py'),
('DataTreeWidget', 'DataTreeWidget.py'),
('GradientWidget', 'GradientWidget.py'),
('TableWidget', 'TableWidget.py'),
('ColorButton', 'ColorButton.py'),
#('CheckTable', '../widgets/CheckTable.py'),
#('VerticalLabel', '../widgets/VerticalLabel.py'),
('JoystickButton', 'JoystickButton.py'),
])),
('Flowcharts', 'Flowchart.py'),
('Custom Flowchart Nodes', 'FlowchartCustomNode.py'),
])
# based on https://github.com/art1415926535/PyQt5-syntax-highlighting
@ -397,15 +316,23 @@ class ExampleLoader(QtGui.QMainWindow):
self.hl = PythonHighlighter(self.ui.codeView.document())
def populateTree(self, root, examples):
bold_font = None
for key, val in examples.items():
item = QtGui.QTreeWidgetItem([key])
self.itemCache.append(item) # PyQt 4.9.6 no longer keeps references to these wrappers,
# so we need to make an explicit reference or else the .file
# attribute will disappear.
if isinstance(val, basestring):
item.file = val
else:
if isinstance(val, OrderedDict):
self.populateTree(item, val)
elif isinstance(val, Namespace):
item.file = val.filename
if 'recommended' in val:
if bold_font is None:
bold_font = item.font(0)
bold_font.setBold(True)
item.setFont(0, bold_font)
else:
item.file = val
root.addChild(item)
def currentFile(self):

View File

@ -1,32 +0,0 @@
# Form implementation generated from reading ui file 'examples\designerExample.ui'
#
# Created by: PyQt6 UI code generator 6.0.0
#
# WARNING: Any manual changes made to this file will be lost when pyuic6 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt6 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):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "PyQtGraph"))
self.plotBtn.setText(_translate("Form", "Plot!"))
from pyqtgraph import PlotWidget

View File

@ -1,32 +0,0 @@
# -*- 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

@ -1,45 +0,0 @@
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'designerExample.ui'
##
## Created by: Qt User Interface Compiler version 6.0.0
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from pyqtgraph import PlotWidget
class Ui_Form(object):
def setupUi(self, Form):
if not Form.objectName():
Form.setObjectName(u"Form")
Form.resize(400, 300)
self.gridLayout = QGridLayout(Form)
self.gridLayout.setObjectName(u"gridLayout")
self.plotBtn = QPushButton(Form)
self.plotBtn.setObjectName(u"plotBtn")
self.gridLayout.addWidget(self.plotBtn, 0, 0, 1, 1)
self.plot = PlotWidget(Form)
self.plot.setObjectName(u"plot")
self.gridLayout.addWidget(self.plot, 1, 0, 1, 1)
self.retranslateUi(Form)
QMetaObject.connectSlotsByName(Form)
# setupUi
def retranslateUi(self, Form):
Form.setWindowTitle(QCoreApplication.translate("Form", u"PyQtGraph", None))
self.plotBtn.setText(QCoreApplication.translate("Form", u"Plot!", None))
# retranslateUi

View File

@ -2,8 +2,6 @@
from __future__ import print_function, division, absolute_import
from collections import namedtuple
from pyqtgraph import Qt
from pyqtgraph.python2_3 import basestring
from .ExampleApp import examples
import errno
import importlib
@ -13,27 +11,33 @@ import os, sys
import platform
import subprocess
import time
from argparse import Namespace
if __name__ == "__main__" and (__package__ is None or __package__==''):
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parent_dir)
import examples
__package__ = "examples"
from . import utils
def buildFileList(examples, files=None):
if files is None:
files = [("Example App", "test_ExampleApp.py")]
files = []
for key, val in examples.items():
if isinstance(val, basestring):
files.append((key,val))
else:
if isinstance(val, dict):
buildFileList(val, files)
elif isinstance(val, Namespace):
files.append((key, val.filename))
else:
files.append((key, val))
return files
path = os.path.abspath(os.path.dirname(__file__))
files = sorted(set(buildFileList(examples)))
files = [("Example App", "test_ExampleApp.py")]
for ex in [utils.examples, utils.others]:
files = buildFileList(ex, files)
files = sorted(set(files))
frontends = {
Qt.PYQT5: False,
Qt.PYQT6: False,
@ -66,6 +70,14 @@ conditionalExamples = {
False,
reason="Test is being problematic on CI machines"
),
"RemoteGraphicsView.py": exceptionCondition(
not(platform.system() == "Darwin"),
reason="FileNotFoundError for pyqtgraph_shmem_* file"
),
"ProgressDialog.py": exceptionCondition(
not(platform.system() == "Linux"),
reason="QXcbConnection: XCB error"
),
'GLVolumeItem.py': exceptionCondition(
not(platform.system() == "Darwin" and
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
@ -145,6 +157,26 @@ conditionalExamples = {
"pyopenGL cannot find openGL libray on big sur: "
"https://github.com/python/cpython/pull/21241"
)
),
'GLBarGraphItem.py': exceptionCondition(
not(platform.system() == "Darwin" and
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
(sys.version_info <= (3, 8, 7) or
(sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
"pyopenGL cannot find openGL libray on big sur: "
"https://github.com/python/cpython/pull/21241"
)
),
'GLViewWidget.py': exceptionCondition(
not(platform.system() == "Darwin" and
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and
(sys.version_info <= (3, 8, 7) or
(sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))),
reason=(
"pyopenGL cannot find openGL libray on big sur: "
"https://github.com/python/cpython/pull/21241"
)
)
}

View File

@ -1,14 +1,10 @@
from __future__ import division, print_function, absolute_import
import os
from pyqtgraph.pgcollections import OrderedDict
from pyqtgraph.python2_3 import basestring
path = os.path.abspath(os.path.dirname(__file__))
from collections import OrderedDict
from argparse import Namespace
examples = OrderedDict([
('Command-line usage', 'CLIexample.py'),
('Basic Plotting', 'Plotting.py'),
('Basic Plotting', Namespace(filename='Plotting.py', recommended=True)),
('ImageView', 'ImageView.py'),
('ParameterTree', 'parametertree.py'),
('Crosshair / Mouse interaction', 'crosshair.py'),
@ -16,7 +12,7 @@ examples = OrderedDict([
('Plot Customization', 'customPlot.py'),
('Timestamps on x axis', 'DateAxisItem.py'),
('Image Analysis', 'imageAnalysis.py'),
('ViewBox Features', 'ViewBoxFeatures.py'),
('ViewBox Features', Namespace(filename='ViewBoxFeatures.py', recommended=True)),
('Dock widgets', 'dockarea.py'),
('Console', 'ConsoleWidget.py'),
('Histograms', 'histogram.py'),
@ -90,14 +86,35 @@ examples = OrderedDict([
])
def buildFileList(examples, files=None):
if files == None:
files = []
for key, val in examples.items():
#item = QtGui.QTreeWidgetItem([key])
if isinstance(val, basestring):
#item.file = val
files.append((key,val))
else:
buildFileList(val, files)
return files
# don't care about ordering
# but actually from Python 3.7, dict is ordered
others = dict([
('logAxis', 'logAxis.py'),
('PanningPlot', 'PanningPlot.py'),
('MultiplePlotAxes', 'MultiplePlotAxes.py'),
('ROItypes', 'ROItypes.py'),
('ScaleBar', 'ScaleBar.py'),
('InfiniteLine', 'InfiniteLine.py'),
('ViewBox', 'ViewBox.py'),
('GradientEditor', 'GradientEditor.py'),
('GLBarGraphItem', 'GLBarGraphItem.py'),
('GLViewWidget', 'GLViewWidget.py'),
('DiffTreeWidget', 'DiffTreeWidget.py'),
('MultiPlotWidget', 'MultiPlotWidget.py'),
('RemoteGraphicsView', 'RemoteGraphicsView.py'),
('colorMaps', 'colorMaps.py'),
('contextMenu', 'contextMenu.py'),
('designerExample', 'designerExample.py'),
('DateAxisItem_QtDesigner', 'DateAxisItem_QtDesigner.py'),
('GraphicsScene', 'GraphicsScene.py'),
('MouseSelection', 'MouseSelection.py'),
('ProgressDialog', 'ProgressDialog.py'),
])
# examples that are subsumed into other examples
trivial = dict([
('SimplePlot', 'SimplePlot.py'), # Plotting.py
('LogPlotTest', 'LogPlotTest.py'), # Plotting.py
('ViewLimits', 'ViewLimits.py'), # ViewBoxFeatures.py
])