diff --git a/examples/DateAxisItem_QtDesigner.py b/examples/DateAxisItem_QtDesigner.py index f6f17489..d92a7503 100644 --- a/examples/DateAxisItem_QtDesigner.py +++ b/examples/DateAxisItem_QtDesigner.py @@ -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() diff --git a/examples/ExampleApp.py b/examples/ExampleApp.py index 44fdb5ec..cb57e3d0 100644 --- a/examples/ExampleApp.py +++ b/examples/ExampleApp.py @@ -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): diff --git a/examples/designerExample_pyqt6.py b/examples/designerExample_pyqt6.py deleted file mode 100644 index 4145e6a9..00000000 --- a/examples/designerExample_pyqt6.py +++ /dev/null @@ -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 diff --git a/examples/designerExample_pyside2.py b/examples/designerExample_pyside2.py deleted file mode 100644 index 1e04c1ac..00000000 --- a/examples/designerExample_pyside2.py +++ /dev/null @@ -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 diff --git a/examples/designerExample_pyside6.py b/examples/designerExample_pyside6.py deleted file mode 100644 index ebe97291..00000000 --- a/examples/designerExample_pyside6.py +++ /dev/null @@ -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 - diff --git a/examples/test_examples.py b/examples/test_examples.py index f3ffcebd..9335011c 100644 --- a/examples/test_examples.py +++ b/examples/test_examples.py @@ -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" + ) ) } diff --git a/examples/utils.py b/examples/utils.py index 4302d82c..225ce327 100644 --- a/examples/utils.py +++ b/examples/utils.py @@ -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 +])