CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
__init__.py400 linesDownload Raw Back to pyqtgraph
1"""2PyQtGraph - Scientific Graphics and GUI Library for Python3www.pyqtgraph.org4"""5 6__version__ = '0.14.0'7 8### import all the goodies and add some helper functions for easy CLI use9 10import importlib11import os12import sys13 14import numpy  # # pyqtgraph requires numpy15 16## 'Qt' is a local module; it is intended mainly to cover up the differences17## between PyQt and PySide.18from .colors import palette19from .Qt import QtCore, QtGui, QtWidgets20from .Qt import exec_ as exec21from .Qt import mkQApp22 23## not really safe--If we accidentally create another QApplication, the process hangs (and it is very difficult to trace the cause)24#if QtWidgets.QApplication.instance() is None:25    #app = QtWidgets.QApplication([])26 27              ## (import here to avoid massive error dump later on if numpy is not available)28 29 30CONFIG_OPTIONS = {31    'useOpenGL': False, ## Set to True or False to explicitly enable/disable opengl.32    'leftButtonPan': True,  ## if false, left button drags a rubber band for zooming in viewbox33    # foreground/background take any arguments to the 'mkColor' in /pyqtgraph/functions.py34    'foreground': 'd',  ## default foreground color for axes, labels, etc.35    'background': 'k',        ## default background for GraphicsWidget36    'antialias': False,37    'editorCommand': None,  ## command used to invoke code editor from ConsoleWidgets38    'exitCleanup': True,    ## Attempt to work around some exit crash bugs in PyQt and PySide39    'enableExperimental': False, ## Enable experimental features (the curious can search for this key in the code)40    'crashWarning': False,  # If True, print warnings about situations that may result in a crash41    'mouseRateLimit': 100,  # For ignoring frequent mouse events, max number of mouse move events per second, if <= 0, then it is switched off42    'imageAxisOrder': 'col-major',  # For 'row-major', image data is expected in the standard (row, col) order.43                                 # For 'col-major', image data is expected in reversed (col, row) order.44                                 # The default is 'col-major' for backward compatibility, but this may45                                 # change in the future.46    'useCupy': False,  # When True, attempt to use cupy ( currently only with ImageItem and related functions )47    'useNumba': False, # When True, use numba48    'segmentedLineMode': 'auto',  # segmented line mode, controls if lines are plotted in segments or continuous49                                  # 'auto': whether lines are plotted in segments is automatically decided using pen properties and whether anti-aliasing is enabled50                                  # 'on' or True: lines are always plotted in segments51                                  # 'off' or False: lines are never plotted in segments52}53 54 55def setConfigOption(opt, value):56    if opt not in CONFIG_OPTIONS:57        raise KeyError('Unknown configuration option "%s"' % opt)58    if opt == 'imageAxisOrder' and value not in ('row-major', 'col-major'):59        raise ValueError('imageAxisOrder must be either "row-major" or "col-major"')60    if opt == 'segmentedLineMode' and value not in ('auto', 'on', 'off'):61        raise ValueError('segmentedLineMode must be "auto", "on" or "off"')62    CONFIG_OPTIONS[opt] = value63 64def setConfigOptions(**opts):65    """Set global configuration options.66 67    Each keyword argument sets one global option.68    """69    for k,v in opts.items():70        setConfigOption(k, v)71 72def getConfigOption(opt):73    """Return the value of a single global configuration option.74    """75    return CONFIG_OPTIONS[opt]76 77 78def systemInfo():79    print("sys.platform: %s" % sys.platform)80    print("sys.version: %s" % sys.version)81    from .Qt import VERSION_INFO82    print("qt bindings: %s" % VERSION_INFO)83 84    global __version__85    rev = None86    if __version__ is None:  ## this code was probably checked out from bzr; look up the last-revision file87        lastRevFile = os.path.join(os.path.dirname(__file__), '..', '.bzr', 'branch', 'last-revision')88        if os.path.exists(lastRevFile):89            with open(lastRevFile, 'r') as fd:90                rev = fd.read().strip()91 92    print("pyqtgraph: %s; %s" % (__version__, rev))93    print("config:")94    import pprint95    pprint.pprint(CONFIG_OPTIONS)96 97## Rename orphaned .pyc files. This is *probably* safe :)98## We only do this if __version__ is None, indicating the code was probably pulled99## from the repository.100def renamePyc(startDir):101    ### Used to rename orphaned .pyc files102    ### When a python file changes its location in the repository, usually the .pyc file103    ### is left behind, possibly causing mysterious and difficult to track bugs.104 105    ### Note that this is no longer necessary for python 3.2; from PEP 3147:106    ### "If the py source file is missing, the pyc file inside __pycache__ will be ignored.107    ### This eliminates the problem of accidental stale pyc file imports."108 109    printed = False110    startDir = os.path.abspath(startDir)111    for path, dirs, files in os.walk(startDir):112        if '__pycache__' in path:113            continue114        for f in files:115            fileName = os.path.join(path, f)116            base, ext = os.path.splitext(fileName)117            py = base + ".py"118            if ext == '.pyc' and not os.path.isfile(py):119                if not printed:120                    print("NOTE: Renaming orphaned .pyc files:")121                    printed = True122                n = 1123                while True:124                    name2 = fileName + ".renamed%d" % n125                    if not os.path.exists(name2):126                        break127                    n += 1128                print("  " + fileName + "  ==>")129                print("  " + name2)130                os.rename(fileName, name2)131 132path = os.path.split(__file__)[0]133 134# Attempts to work around exit crashes:135import atexit136 137from .colormap import *138from .functions import *139from .graphicsItems.ArrowItem import *140from .graphicsItems.AxisItem import *141from .graphicsItems.BarGraphItem import *142from .graphicsItems.BoxplotItem import *143from .graphicsItems.ButtonItem import *144from .graphicsItems.ColorBarItem import *145from .graphicsItems.CurvePoint import *146from .graphicsItems.DateAxisItem import *147from .graphicsItems.ErrorBarItem import *148from .graphicsItems.FillBetweenItem import *149from .graphicsItems.GradientEditorItem import *150from .graphicsItems.GradientLegend import *151from .graphicsItems.GraphicsItem import *152from .graphicsItems.GraphicsLayout import *153from .graphicsItems.GraphicsObject import *154from .graphicsItems.GraphicsWidget import *155from .graphicsItems.GraphicsWidgetAnchor import *156from .graphicsItems.GraphItem import *157from .graphicsItems.GridItem import *158from .graphicsItems.HistogramLUTItem import *159from .graphicsItems.ImageItem import *160from .graphicsItems.InfiniteLine import *161from .graphicsItems.IsocurveItem import *162from .graphicsItems.ItemGroup import *163from .graphicsItems.LabelItem import *164from .graphicsItems.LegendItem import *165from .graphicsItems.LinearRegionItem import *166from .graphicsItems.PColorMeshItem import *167from .graphicsItems.PlotCurveItem import *168from .graphicsItems.PlotDataItem import *169from .graphicsItems.PlotItem import *170from .graphicsItems.ROI import *171from .graphicsItems.ScaleBar import *172from .graphicsItems.ScatterPlotItem import *173from .graphicsItems.TargetItem import *174from .graphicsItems.TextItem import *175from .graphicsItems.UIGraphicsItem import *176from .graphicsItems.ViewBox import *177from .graphicsItems.VTickGroup import *178 179# indirect imports used within library180from .GraphicsScene import GraphicsScene181from .imageview import *182 183# indirect imports known to be used outside of the library184from .Point import Point185from .Qt import isQObjectAlive186from .SignalProxy import *187from .SRTTransform import SRTTransform188from .SRTTransform3D import SRTTransform3D189from .ThreadsafeTimer import *190from .Transform3D import Transform3D191from .util.cupy_helper import getCupy192from .Vector import Vector193from .WidgetGroup import *194from .widgets.BusyCursor import *195from .widgets.CheckTable import *196from .widgets.ColorButton import *197from .widgets.ColorMapMenu import ColorMapMenu198from .widgets.ColorMapWidget import *199from .widgets.ComboBox import *200from .widgets.DataFilterWidget import *201from .widgets.DataTreeWidget import *202from .widgets.DiffTreeWidget import *203from .widgets.FeedbackButton import *204from .widgets.FileDialog import *205from .widgets.GradientWidget import *206from .widgets.GraphicsLayoutWidget import *207from .widgets.GraphicsView import *208from .widgets.GroupBox import GroupBox209from .widgets.HistogramLUTWidget import *210from .widgets.JoystickButton import *211from .widgets.LayoutWidget import *212from .widgets.PathButton import *213from .widgets.PlotWidget import *214from .widgets.ProgressDialog import *215from .widgets.RawImageWidget import *216from .widgets.RemoteGraphicsView import RemoteGraphicsView217from .widgets.ScatterPlotWidget import *218from .widgets.SpinBox import *219from .widgets.TableWidget import *220from .widgets.TreeWidget import *221from .widgets.ValueLabel import *222from .widgets.VerticalLabel import *223 224##############################################################225## PyQt and PySide both are prone to crashing on exit.226## There are two general approaches to dealing with this:227##  1. Install atexit handlers that assist in tearing down to avoid crashes.228##     This helps, but is never perfect.229##  2. Terminate the process before python starts tearing down230##     This is potentially dangerous231 232_cleanupCalled = False233def cleanup():234    global _cleanupCalled235    if _cleanupCalled:236        return237 238    if not getConfigOption('exitCleanup'):239        return240 241    ViewBox.quit()  ## tell ViewBox that it doesn't need to deregister views anymore.242 243    _cleanupCalled = True244 245atexit.register(cleanup)246 247# Call cleanup when QApplication quits. This is necessary because sometimes248# the QApplication will quit before the atexit callbacks are invoked.249# Note: cannot connect this function until QApplication has been created, so250# instead we have GraphicsView.__init__ call this for us.251_cleanupConnected = False252def _connectCleanup():253    global _cleanupConnected254    if _cleanupConnected:255        return256    QtWidgets.QApplication.instance().aboutToQuit.connect(cleanup)257    _cleanupConnected = True258 259 260## Optional function for exiting immediately (with some manual teardown)261def exit():262    """263    Causes python to exit without garbage-collecting any objects, and thus avoids264    calling object destructor methods. This is a sledgehammer workaround for265    a variety of bugs in PyQt and Pyside that cause crashes on exit.266 267    This function does the following in an attempt to 'safely' terminate268    the process:269 270      * Invoke atexit callbacks271      * Close all open file handles272      * os._exit()273 274    Note: there is some potential for causing damage with this function if you275    are using objects that _require_ their destructors to be called (for example,276    to properly terminate log files, disconnect from devices, etc). Situations277    like this are probably quite rare, but use at your own risk.278    """279 280    ## first disable our own cleanup function; won't be needing it.281    setConfigOptions(exitCleanup=False)282 283    ## invoke atexit callbacks284    atexit._run_exitfuncs()285 286    ## close file handles287    if sys.platform == 'darwin':288        for fd in range(3, 4096):289            if fd in [7]:  # trying to close 7 produces an illegal instruction on the Mac.290                continue291            try:292                os.close(fd)293            except OSError:294                pass295    else:296        os.closerange(3, 4096) ## just guessing on the maximum descriptor count..297 298    os._exit(0)299 300 301## Convenience functions for command-line use302plots = []303images = []304QAPP = None305 306def plot(*args, **kargs):307    """308    Create and return a :class:`PlotWidget <pyqtgraph.PlotWidget>`309    Accepts a *title* argument to set the title of the window.310    All other arguments are used to plot data. (see :func:`PlotItem.plot() <pyqtgraph.PlotItem.plot>`)311    """312    mkQApp()313    pwArgList = ['title', 'labels', 'name', 'left', 'right', 'top', 'bottom', 'background']314    pwArgs = {}315    dataArgs = {}316    for k in kargs:317        if k in pwArgList:318            pwArgs[k] = kargs[k]319        else:320            dataArgs[k] = kargs[k]321    windowTitle = pwArgs.pop("title", "PlotWidget")322    w = PlotWidget(**pwArgs)323    w.setWindowTitle(windowTitle)324    if len(args) > 0 or len(dataArgs) > 0:325        w.plot(*args, **dataArgs)326    plots.append(w)327    w.show()328    return w329 330def image(*args, **kargs):331    """332    Create and return an :class:`ImageView <pyqtgraph.ImageView>`333    Will show 2D or 3D image data.334    Accepts a *title* argument to set the title of the window.335    All other arguments are used to show data. (see :func:`ImageView.setImage() <pyqtgraph.ImageView.setImage>`)336    """337    mkQApp()338    w = ImageView()339    windowTitle = kargs.pop("title", "ImageView")340    w.setWindowTitle(windowTitle)341    w.setImage(*args, **kargs)342    images.append(w)343    w.show()344    return w345show = image  ## for backward compatibility346 347 348def dbg(*args, **kwds):349    """350    Create a console window and begin watching for exceptions.351 352    All arguments are passed to :func:`ConsoleWidget.__init__() <pyqtgraph.console.ConsoleWidget.__init__>`.353    """354    mkQApp()355    from . import console356    c = console.ConsoleWidget(*args, **kwds)357    c.catchAllExceptions()358    c.show()359    global consoles360    try:361        consoles.append(c)362    except NameError:363        consoles = [c]364    return c365 366 367def stack(*args, **kwds):368    """369    Create a console window and show the current stack trace.370 371    All arguments are passed to :func:`ConsoleWidget.__init__() <pyqtgraph.console.ConsoleWidget.__init__>`.372    """373    mkQApp()374    from . import console375    c = console.ConsoleWidget(*args, **kwds)376    c.setStack()377    c.show()378    global consoles379    try:380        consoles.append(c)381    except NameError:382        consoles = [c]383    return c384 385 386def setPalette(app, style):387    if isinstance(style, str):388        style = style.lower()389        if style == 'qdarkstylelight':390            p = palette.getQDarkStyleLightQPalette()391        elif style in ['qdarkstyle','qdarkstyledark']:392            p = palette.getQDarkStyleDarkQPalette()393        else:394            raise ValueError(f'no palette by the name {style} exists')395    elif isinstance(style, QtGui.QPalette):396        p = style397    else:398        raise TypeError('style either be a string or QPalette')399    app.setPalette(p)400 
Aluode/PerceptionLabPortable · CoolFace