Skip to content

Commit 0f196a7

Browse files
committed
DOC: first additions to docs about pyside6, also add tag for parts of codebase where we do pyqt5/pyside6 specific things.
1 parent 9ff9dbf commit 0f196a7

24 files changed

+111
-30
lines changed

.github/workflows/run-tests.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ jobs:
2626
pyqt-version: ["5.12.3", "5.15.11"] # we still use 5.12.3 since newer conda versions have designer plugin issues
2727
exclude:
2828
# don't run these
29-
- python-version: "3.10" # 5.15.11 is newest pyqt5, so use newest python (3.12)
30-
pyqt-version: "5.15.11"
29+
- python-version: "3.10" # 5.15.11 is newest pyqt5, so use newest python (3.12)
30+
pyqt-version: "5.15.11"
3131
- python-version: "3.12" # max python version for 5.12.3 is 3.10 (3.12 errors during conda env creation)
32-
pyqt-version: "5.12.3"
32+
pyqt-version: "5.12.3"
3333
env:
3434
DISPLAY: ':99.0'
3535
QT_MAC_WANTS_LAYER: 1 # PyQT gui tests involving qtbot interaction on macOS will fail without this

CONTRIBUTING.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ Ready to contribute? Here's how to set up `pydm` for local development.
6464
3. Install your local copy into a new conda environment. Assuming you have conda installed, this is how you set up your fork for local development::
6565

6666
$ conda create -n pydm-environment python=3.10 pyqt=5.12.3 pip numpy scipy six psutil pyqtgraph -c conda-forge
67+
$ source pydm-environment
68+
$ cd pydm/
69+
$ pip install -e .
70+
71+
PyDM also supports running on PySide6 (atm functionality is the same on both PyQt5 and PySide6)
72+
73+
$ conda create -n pydm-environment-pyside6 python pyside6 pip numpy scipy six psutil pyqtgraph -c conda-forge
74+
$ source pydm-environment-environment
6775
$ cd pydm/
6876
$ pip install -e .
6977

@@ -72,6 +80,12 @@ Ready to contribute? Here's how to set up `pydm` for local development.
7280
$ pip install -r dev-requirements.txt
7381
$ pip install -r docs-requirements.txt
7482

83+
5: Now you should be able to launch pydm as follows:
84+
85+
$ export QT_API=pyqt5 # can also set to `pyside6`, this determines which python wrapper pydm will use (wrapper must be installed in conda env)
86+
$ pydm # launches an empty main-window
87+
$ pydm example.ui # launches PyDM screen
88+
7589
5. Create a branch for local development::
7690

7791
$ git checkout -b name-of-your-bugfix-or-feature

README.md

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</p>
99

1010
<p align="left">
11-
PyDM is a PyQt-based framework for building user interfaces for control systems.
11+
PyDM is a Python Qt based framework for building user interfaces for control systems.
1212
The goal is to provide a no-code, drag-and-drop system to make simple screens,
1313
as well as a straightforward Python framework to build complex applications.
1414
<br>
@@ -31,18 +31,18 @@
3131

3232
# Python Qt Wrapper
3333
PyDM project uses the [qtpy](https://github.com/spyder-ide/qtpy)
34-
as the abstraction layer for the Qt Python wrappers (PyQt5/PyQt4/PySide2/PySide).
35-
**All tests are performed with PyQt5**.
34+
as the abstraction layer for the Qt Python wrappers.
35+
**All tests are performed with PyQt5 and PySide6**.
3636

3737
# Prerequisites
3838
* Python 3.10+
3939
* Qt 5.6 or higher
4040
* qtpy
41-
* PyQt5 >= 5.7 or any other Qt Python wrapper.
41+
* PyQt5 >= 5.7 or PySide6 >= 6.9.
4242
> **Note:**
4343
> If you'd like to use Qt Designer (drag-and-drop tool to build interfaces) you'll
44-
> need to make sure you have the PyQt plugin for Designer installed. This usually
45-
> happens automatically when you install PyQt from source, but if you install it
44+
> need to make sure you have the PyQt/PySide6 plugin for Designer installed. This usually
45+
> happens automatically when you install PyQt/PySide6 from source, but if you install it
4646
> from a package manager, it may be left out.
4747
4848
Python package requirements are listed in the requirements.txt file, which can
@@ -104,11 +104,16 @@ Documentation is available at http://slaclab.github.io/pydm/. Documentation is
104104
somewhat sparse right now, unfortunately.
105105

106106
# Widget Designer Plugins
107-
pydm widgets are written in Python, and are loaded into Qt Designer via the PyQt
107+
PyDM widgets are written in Python, and are loaded into Qt Designer via the PyQt/PySide6.
108108
Designer Plugin.
109-
If you want to use the pydm widgets in Qt Designer, add the pydm directory
110-
(which holds designer_plugin.py) to your PYQTDESIGNERPATH environment variable.
111-
Eventually, this will happen automatically in some kind of setup script.
109+
110+
This should happen automatically if you use conda to install PyDM on Linux.
111+
For PyQt5, will automatically define the `PYQTDESIGNERPATH` environment variable to point to /etc/pydm which
112+
will have a file named `designer_plugin.py` which will make all the PyDM widgets available to the Qt Designer.
113+
For PySide6, `PYSIDE_DESIGNER_PLUGINS` (on Pyside6) will point to /etc/pydm where `register_pydm_designer_plugin.py` is found.
114+
For more information please see our <a href="https://slaclab.github.io/pydm/installation.html">installation guide</a>.
115+
116+
To do this manually, add the pydm directory to your PYQTDESIGNERPATH environment variable.
112117

113118
# Easy Installing PyDM
114119
## Using the source code
@@ -117,11 +122,3 @@ git clone https://github.com/slaclab/pydm.git
117122
cd pydm
118123
pip install .[all]
119124
```
120-
121-
## Using Anaconda
122-
123-
When using Anaconda to install PyDM at a Linux Environment it will automatically
124-
define the PYQTDESIGNERPATH environment variable pointing to /etc/pydm which
125-
will have a file named designer_plugin.py which will make all the PyDM widgets
126-
available to the Qt Designer. For more information please see
127-
our <a href="https://slaclab.github.io/pydm/installation.html">installation guide</a>.

conda-recipe/meta.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ about:
4444
license_file: LICENSE.md
4545
summary: 'Python Display Manager'
4646
description: |
47-
PyDM is a PyQt-based framework for building user interfaces for control systems.
47+
PyDM is a Python-Qt based framework for building user interfaces for control systems.
4848
The goal is to provide a no-code, drag-and-drop system to make simple screens,
4949
as well as a straightforward Python framework to build complex applications.
5050
doc_url: https://slaclab.github.io/pydm/

docs/source/development/development.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,27 @@ should look like this:
139139
working on that branch. The rebasing process re-writes the commit history so
140140
any other checkout of the same branch referring to the old history will
141141
create duplicates of all the commits.
142+
143+
Qt Wrapper Dependent Code
144+
===========================
145+
PyDM is written in Python using wrappers around the C++ Qt library. PyDM currently supports two different python wrappers: PyQt5 and PySide6.
146+
PyQt5 runs on the older Qt version Qt5, and PySide6 runs the on the newest Qt version Qt6.
147+
But atm, the functionality of PyDM should be the same regardless of if PyQt5 or PySide6 is used.
148+
149+
PyDM also runs on-top of an abstraction layer called "qtpy" (https://github.com/spyder-ide/qtpy), which ideally allows for a codebase to run
150+
on both PyQt and PySide6 without any wrapper-specific modifications.
151+
152+
But in reality, there are still places in the PyDM codebase where it was needed to implement
153+
PyQt5/PySide6 specific code, either b/c qtpy was lacking an abstraction around certainn Qt features
154+
or b/c the code worked abstraction layer in the past and is difficult to change.
155+
156+
These wrapper-specific sections are noted in the codebase by the ``@QT_WRAPPER_SPECIFIC`` string. There are also comments in
157+
these sections explaining the differences between the PyQt and Pyside6 implementations.
158+
159+
When changing code marked with ``@QT_WRAPPER_SPECIFIC``, developers must take special care to ensure their changes work on both PyQt and PySide6.
160+
It should be the case that automated testing on GitHub will run with both wrappers before any code is merged.
161+
But, if changing a ``@QT_WRAPPER_SPECIFIC`` section it's recommended to have setup a conda environments with both PyQt and
162+
PySide6 installed so you can test PyDM locally with both wrappers. Also, ew sections of PyQt5/PySide6 specific code should also marked with the ``@QT_WRAPPER_SPECIFIC`` string.
163+
164+
If any new features are added to PyDM that utilize new Qt6 functionality (and therefore will only work on PySide6),
165+
these sections should also get denoted with the ``@QT_WRAPPER_SPECIFIC`` string.

docs/source/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
PyDM - Python Display Manager
22
=============================
33

4-
PyDM is a PyQt-based framework for building user interfaces for control systems.
4+
PyDM is a Python-Qt based framework for building user interfaces for control systems.
55

66
The goal is to provide a no-code, drag-and-drop system to make simple screens,
77
as well as a straightforward python framework to build complex applications.

docs/source/installation.rst

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,21 @@ from scratch is probably using the Conda system. We recommended using Conda from
99
python environment, and want to install PyDM for use with that, you can do that
1010
with pip.
1111

12+
PyDM runs using Python wrappers on-top of C++ Qt, and currently supports running on PyQt5 (Qt5) and PySide6 (Qt6).
13+
Atm, PyQt5 is the recommended choice to run with, whereas PySide6 provides future-proofing and the potential for new Qt6 specific features.
14+
(Note: currently functionality is the same between PyQt and PySide6)
15+
16+
In general, running PyDM with a chosen Python wrapper can be done as follows:
17+
load a conda environment that has installed PyDM and the wrapper(s) you wish to use (along with the other required packages),
18+
and then set the `QT_API` environment var to either `pyqt5`` or `pyside6`.
19+
Then when PyDM is launched it will automatically run on the selected binding.
20+
This binding can be changed at any time, and PyDM will load the selected wrapper on next load.
21+
22+
Instructions for setting up conda environments for PyQt5 and PySide6 are provided later in this doc page.
23+
1224
Please note, this guide is written with Unix in mind, so there are probably some differences when installing on Windows.
1325

14-
Installing PyDM and Prerequisites with Conda
26+
Installing PyDM and Prerequisites with Conda (PyQt5)
1527
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1628

1729
.. warning::
@@ -48,7 +60,21 @@ Now, you can use 'open' to open Designer.app::
4860

4961
$ export QT_MAC_WANTS_LAYER=1
5062

51-
Installing Manually, Without Anaconda
63+
Installing PyDM and Prerequisites with Conda (PySide6)
64+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
65+
66+
After installing Miniforge (see https://conda-forge.org/download/), create a new
67+
environment for PyDM::
68+
69+
$ conda create -n pydm-environment-pyside python pip numpy scipy six psutil pyqtgraph pyside6 pydm -c conda-forge
70+
$ source activate pydm-environment
71+
$ export QT_API=pyside6
72+
73+
Once you've installed and activated the environment, you should be able to run 'pydm' to launch PyDM or run 'designer6' to launch QtDesigner.
74+
75+
MacOS and Windows instructions coming soon...
76+
77+
Installing Manually, Without Anaconda (PyQt5)
5278
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5379
This alternate installation method is only recommended for large 'site' installations that want to avoid using Anaconda.
5480

@@ -78,6 +104,10 @@ and extract the archive. Follow `the provided instructions <http://pyqt.sourcef
78104
build and install it. Note that you may need to manually set the '--qmake' option to point to the
79105
qmake binary you created when you built Qt5.
80106

107+
Installing Manually, Without Anaconda (PySide6)
108+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
109+
Coming soon...
110+
81111
Installing PyDM with PIP
82112
++++++++++++++++++++++++
83113

examples/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# pydm-examples: Python Display Manager Examples
2-
[PyDM](https://github.com/slaclab/pydm) is a PyQt-based framework for building user interfaces for control systems. The goal is to provide a no-code, drag-and-drop system to make simple screens, as well as a straightforward python framework to build complex applications.
2+
[PyDM](https://github.com/slaclab/pydm) is a Python-Qt based framework for building user interfaces for control systems. The goal is to provide a no-code, drag-and-drop system to make simple screens, as well as a straightforward python framework to build complex applications.
33

44
# Prerequisites for the examples
5-
* Python 3.6+
5+
* Python 3.10+
66
* pydm
77
* Qt 5.7 or higher
8-
* PyQt5 >= 5.7
8+
* PyQt5 >= 5.7 or PySide6 6.9
99
* pcaspy (Optional)
1010
pcaspy is needed for the `pydm-testing-ioc` used in most of the examples.
1111

pydm/display.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ def _compile_ui_file(uifile: str) -> Tuple[str, str]:
9898
-------
9999
Tuple[str, str] - The first element is the compiled ui file, the second is the name of the class (e.g. Ui_Form)
100100
"""
101+
# @QT_WRAPPER_SPECIFIC
101102
if ACTIVE_QT_WRAPPER == QtWrapperTypes.PYQT5:
102103
code_string = StringIO()
103104
uic.compileUi(uifile, code_string)
@@ -126,6 +127,7 @@ def _compile_ui_file(uifile: str) -> Tuple[str, str]:
126127

127128

128129
def _load_ui_into_display(uifile, display):
130+
# @QT_WRAPPER_SPECIFIC
129131
if ACTIVE_QT_WRAPPER == QtWrapperTypes.PYQT5:
130132
klass, _ = uic.loadUiType(uifile)
131133
else: # pyside6

pydm/tests/test_display.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def ui_filename(self):
4848
qtbot.addWidget(my_display)
4949

5050

51+
# @QT_WRAPPER_SPECIFIC
5152
if ACTIVE_QT_WRAPPER == QtWrapperTypes.PYQT5:
5253

5354
def test_nonexistent_ui_file_raises_pyqt5(qtbot):

0 commit comments

Comments
 (0)