{"id":16589170,"url":"https://github.com/ixjlyons/embed-pyqtgraph-tutorial","last_synced_at":"2025-03-23T14:31:07.478Z","repository":{"id":145085570,"uuid":"63823748","full_name":"ixjlyons/embed-pyqtgraph-tutorial","owner":"ixjlyons","description":"Demonstration of embedding pyqtgraph plots in a PyQt UI using Qt Designer","archived":false,"fork":false,"pushed_at":"2018-11-01T17:54:31.000Z","size":25,"stargazers_count":34,"open_issues_count":2,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-18T21:08:26.379Z","etag":null,"topics":["pyqt","pyqtgraph","qt","qtdesigner"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ixjlyons.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-21T00:28:00.000Z","updated_at":"2024-11-24T06:00:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"54061e26-8b98-49ff-86d2-b81f268a98a0","html_url":"https://github.com/ixjlyons/embed-pyqtgraph-tutorial","commit_stats":{"total_commits":9,"total_committers":1,"mean_commits":9.0,"dds":0.0,"last_synced_commit":"8d13b235729366f025f2ab66f6c18c1dd222f962"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ixjlyons%2Fembed-pyqtgraph-tutorial","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ixjlyons%2Fembed-pyqtgraph-tutorial/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ixjlyons%2Fembed-pyqtgraph-tutorial/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ixjlyons%2Fembed-pyqtgraph-tutorial/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ixjlyons","download_url":"https://codeload.github.com/ixjlyons/embed-pyqtgraph-tutorial/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245115716,"owners_count":20563215,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pyqt","pyqtgraph","qt","qtdesigner"],"created_at":"2024-10-11T23:07:59.938Z","updated_at":"2025-03-23T14:31:07.445Z","avatar_url":"https://github.com/ixjlyons.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"========================\nembed-pyqtgraph-tutorial\n========================\n\nThis is a walkthrough of embedding pyqtgraph_ content in a PyQt application\nyou're designing with Qt Designer. Here's an overview of the steps involved:\n\n* Create the layout of the UI in Qt Designer (generates ``template.ui``)\n* Compile the XML template to Python source (uses ``build_ui.py`` to generate\n  ``template.py``)\n* Write a custom QWidget class which takes on the UI and populates the embedded\n  pyqtgraph widget (``application.py``)\n\nThe example provided displays a `PlotWidget`_ with some data and a QCheckBox to\nenable/disable mouse control of the plot. It's a simple example, but once\nyou've seen the process of adding pyqtgraph widgets to your UI, you can create\narbitrarily complex applications without having to write a ton of boilerplate\nlayout code.\n\n.. image:: screenshot.png\n\n\nPrerequisites\n=============\n\nI'm going to assume you have some way of creating Qt applications with Python,\nand the instructions here should not be much (if at all) different between the\nways to accomplish that (i.e. PyQt4, PyQt5, PySide, PySide2). For reference,\nI'm using PyQt5 and Python 3, so the following works for setting up an\nenvironment for running the example::\n\n   $ python -m venv .venv\n   $ source .venv/bin/activate\n   (.venv) $ pip install pyqt5 pyqtgraph\n   (.venv) $ python application.py\n\nIf you're using a different setup (e.g. PyQt4, PySide), you'll need to fix some\nimports before being able to run the example application.\n\nI'm also going to assume you have have some knowledge of how to use pyqtgraph.\nThe `pyqtgraph examples`_ cover its capabilities pretty well.\n\n\nTutorial\n========\n\nCreating the UI Layout\n----------------------\n\n::\n\n    ┌────────────┐   ┌─────────────┐   ┌─────────────┐\n    │ creativity │ → │ Qt Designer │ → │ template.ui │\n    └────────────┘   └─────────────┘   └─────────────┘\n\nGenerally, you can use custom widgets in Qt Designer through the `promote`_\nmechanism. This means you add an item of the base class of your custom item to\nyour UI layout, right click on it, then go to \"Promote to ...\". Since we're\nusing Python instead of C++, the \"Header file\" in this case is going to be the\nPython namespace at which you would access the class as though you were\nimporting it. For example, if you had a custom widget class, where an import\nstatement might look like:\n\n.. code:: python\n\n    from myproject.widgets import CustomDialog\n\nyou would put ``myproject.widgets`` in the \"Header file\" field and\n``CustomDialog`` in the \"Promoted class name\" field. The basic Qt class you\ninherit from (e.g. QDialog, QWidget, etc.) is then the \"Base class name.\"\n\npyqtgraph actually provides some documentation for how to embed plotting\nobjects into a Qt UI using Qt Designer (see `embed pyqtgraph`_), but it's a bit\nlacking. In our case, add a QGraphicsView to the layout where you want the plot\nto be, then promote it to a PlotWidget. Most pyqtgraph classes are available\nunder the pyqtgraph namespace, so just put \"pyqtgraph\" in the header file\nfield.\n\nIf you inspect the ``template.ui`` file, you can see towards the bottom there\nis a ``customwidget`` section specifying everything we just covered:\n\n========== ==============\nclass      PlotWidget\nbase class QGraphicsView\nnamespace  pyqtgraph\n========== ==============\n\nCompiling the Layout\n--------------------\n\n::\n\n    ┌─────────────┐   ┌─────────────┐   ┌─────────────┐\n    │ template.ui │ → │ build_ui.py │ → │ template.py │\n    └─────────────┘   └─────────────┘   └─────────────┘\n\nThere are a few ways to turn your UI template into Python code. The first (my\npreferred) way of doing it is to write a little script to grab all of your\n``*.ui`` files and use the `pyuic`_ module to write the corresponding Python\ncode to the desired destination. An example is given here (``build_ui.py``).\nYou can modify the ``SRC`` and ``DEST`` variables if you want to arrange your\nproject structure differently. My recommendation is to put your UI files in\nsomething like ``res/`` and the compiled Python files in your project source to\nmake importing simple (see the next step).\n\nYou could instead use ``pyuic`` directly from the command line. For single UI\ntemplates, this is fine, but you'll want a scripted approach if you end up with\nmore. For reference, here's how you'd convert the template given here::\n\n   (.venv) $ pyuic5 template.ui -o template.py\n\nThe third option would be to use the UI template directly from your\nhand-written Python code (i.e. using ``uic.loadUI()``). I tend to avoid this to\nmake packaging the project easier, but it is probably not all that difficult to\npackage the UI templates. If you're already dealing with packaging custom icon\nfiles and such, this would be a non-issue.\n\nNow, if you take a look at the ``template.py`` file, you'll see there's a class\ncalled ``Ui_CustomWidget`` that has, primarily, a ``setupUi`` method to create\nand lay out all of the content we designed in Qt Designer. This is a pretty\nsimple example, but with complex layouts with many items, the use of Qt\nDesigner and automatic generation of this code really shines.\n\nAlso notice the import line at the bottom of the file:\n\n.. code-block:: python\n\n    from pyqtgraph import PlotWidget\n\nThis all comes straight from that bottom section of the ``template.ui`` file,\nwhere we specified in Qt Designer that we have a custom item of a specific\nclass and where it can be found.\n\nWrapping the UI in a Custom QWidget\n-----------------------------------\n\n::\n\n    ┌─────────────┐   ┌────────────────┐   ┌─────────┐\n    │ template.py │ → │ application.py │ → │ success │\n    └─────────────┘   └────────────────┘   └─────────┘\n\nNow for the difficult part. PyQt provides some documentation for `using the\ngenerated code`_, though it is a little sparse if you don't have the high-level\noverview of the whole process. Essentially, you write a custom class (usually\nQWidget, but really it can be any QWidget-like class such as QMainWindow,\nQDialog, etc.), then use the compiled Python code to access and interact with\nthe layout you specified. The key here is that you *are not modifying the\ngenerated Python code*. That means in our case that we don't want to mess with\n``template.py`` by hand. If you make changes to it, you can no longer make\nchanges to your UI from Qt Designer because re-generating the template will\noverwrite your changes!\n\nThe nice thing about this workflow overall is that it cleans up your custom\nclass code a lot, since you're not creating container layouts all over the\nplace, specifying sizes, size policies, etc.\n\nOur implementation is in ``application.py``. It starts out with importing Qt\nstuff so we can set up a QApplication and run it. We also *import the template\nmodule* so we have access to the template class (PyQt refers to it as the *form\nclass*). We then write a custom QWidget implementation which instantiates the\nform class and calls its ``setupUi`` method. I typically assign the form class\nto an attribute called ``ui``. Once you call ``setupUi``, you now can access\nthe items in your UI through the names they were given in Qt Designer.\n\nSo in our example, we access the ``plotWidget`` attribute of the form class\nobject, which is a pyqtgraph PlotWidget object. Now the pyqtgraph API applies,\nso we can plot some content and whatever else we need. In this case, we connect\nup the checkbox to a method that toggles mouse functionality on the PlotWidget.\n\n*Note: It is possible to make CustomWidget inherit from UI_CustomWidget (so\nyou'd call ``self.setupUi()``), but I prefer to explicitly set up the form\nclass object as an attribute of the custom widget -- mostly because it's very\nclear when you're accessing UI elements specified by Designer rather than\nwidgets you might add programmatically.*\n\n\nOther Notes\n===========\n\nFeel free to open an issue if anything here isn't clear.\n\nI originally wrote this in response to seeing questions on the `pyqtgraph\nmailing list`_ about using pyqtgraph functionality in an application designed\nwith Qt Designer. It's not obvious at all that you can use the promote\nmechanism with PyQt (as opposed to C++ Qt), so I wrote this to help people out.\nFeel free to use these materials in a pull request to improve pyqtgraph\ndocumentation.\n\n\n.. _pyqtgraph: http://pyqtgraph.org/\n.. _PlotWidget: http://pyqtgraph.org/documentation/widgets/plotwidget.html\n.. _pyqtgraph examples: https://github.com/pyqtgraph/pyqtgraph/tree/develop/examples\n.. _embed pyqtgraph: http://pyqtgraph.org/documentation/how_to_use.html#embedding-widgets-inside-pyqt-applications\n.. _promote: http://doc.qt.io/qt-5/designer-using-custom-widgets.html\n.. _pyuic: http://pyqt.sourceforge.net/Docs/PyQt5/designer.html#the-uic-module\n.. _using the generated code: http://pyqt.sourceforge.net/Docs/PyQt5/designer.html\n.. _pyqtgraph mailing list: https://groups.google.com/forum/#!forum/pyqtgraph\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fixjlyons%2Fembed-pyqtgraph-tutorial","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fixjlyons%2Fembed-pyqtgraph-tutorial","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fixjlyons%2Fembed-pyqtgraph-tutorial/lists"}