|
| 1 | +========================== |
| 2 | +Adding a New Vacuum Widget |
| 3 | +========================== |
| 4 | + |
| 5 | +This page details the development process for adding a new vacuum widget. |
| 6 | +It was made during the process of creating the PneumaticValveDA widget. |
| 7 | + |
| 8 | + |
| 9 | +Requirements |
| 10 | +------------ |
| 11 | +You should have the following things in mind before you begin: |
| 12 | + |
| 13 | +- What should the widget look like? |
| 14 | +- Is there any existing widget that this is similar to? |
| 15 | +- What are my interlock, error, state readback, and control PVs? |
| 16 | + |
| 17 | + |
| 18 | +Implementation Overview |
| 19 | +----------------------- |
| 20 | +You'll need to do the following things: |
| 21 | + |
| 22 | +- Add a new icon widget. |
| 23 | +- Add a new valve widget that uses the icon. |
| 24 | +- Add your new widget to the designer. |
| 25 | +- Update stylesheets to be consistent for your new widget. |
| 26 | +- Add a new device class for your widget's expert screen. |
| 27 | + |
| 28 | + |
| 29 | +Adding a New Icon Widget |
| 30 | +------------------------ |
| 31 | +The icon widgets are stored in pcdswidgets/icons and are implemented by |
| 32 | +using the QtGui painter tools. I suggest you pick a class that almost |
| 33 | +does what you want as a starting point. |
| 34 | +With BaseSignalIcon as a parent class, the only method you need to override |
| 35 | +is "draw_icon". Check out the other icons for examples and feel free to |
| 36 | +browse the qt documentation. |
| 37 | +This process will take a lot of iterations |
| 38 | +(edit the file, check the ui, repeat). |
| 39 | +To make this process smoother, I added a script embedded in the icons module. |
| 40 | +Try this to open an application that simply displays a widget: |
| 41 | + |
| 42 | +.. code-block bash |
| 43 | + python -m pcdswidgets.icons.demo ControlValve |
| 44 | +
|
| 45 | +Some tips: |
| 46 | + |
| 47 | +- The coordinate system starts from the top left of the icon, so positive y is down |
| 48 | +- The expected size of the widget icon is from 0 to 1 in both x and y |
| 49 | +- If you want something to be modifyable via stylesheet, PV, etc., you can make it |
| 50 | + a property with qt's @Property flag. This is useful for alarm sensitive coloring, |
| 51 | + for example. |
| 52 | +- When drawing a shape, it's useful to parameterize it even if you only use it once. |
| 53 | + This is because you may later want to edit the specifics, but if your QPolygon |
| 54 | + is just a list of numbers this will be very hard. A list of variables like |
| 55 | + "arrow_length" are easier to modify later. |
| 56 | +- When designing your shape, note that the widget might need to look good at |
| 57 | + different sizes. Pay particular care in designing widget icons with small features, |
| 58 | + these can become indistiguishable as we shrink the shapes down. |
| 59 | + |
| 60 | + |
| 61 | +Adding a New Widget Class |
| 62 | +------------------------- |
| 63 | +Widget classes in pcdswidgets are constructed from a network of mix-ins and parent |
| 64 | +classes. A good place to start is simply copying the most similar existing |
| 65 | +widget and modifying the specifics to match yours. Barring something extremely |
| 66 | +similar existing, you'll need to delve into the specifics of the inner workings |
| 67 | +and I can't encapsulate that in a guide. |
| 68 | + |
| 69 | +In some cases, you may be able to get away with simply copying a widget |
| 70 | +and changing the docstrings, attributes, and super calls as appropriate. |
| 71 | + |
| 72 | +For deeper dives, I recommend looking at each mix-in class in isolation to |
| 73 | +understand how that particular feature is implemented. |
| 74 | + |
| 75 | +You can test your new widget quickly by running the helper script: |
| 76 | + |
| 77 | +.. code-block bash |
| 78 | + python -m pcdswidgets.vacuum.demo PneumaticValveDA CRIX:VGC:11 |
| 79 | +
|
| 80 | +But you should make some screens with it to explore the finer details. |
| 81 | + |
| 82 | + |
| 83 | +Adding your Widget to the Designer |
| 84 | +---------------------------------- |
| 85 | +This is probably the easiest step of the process. Simply import your new widget |
| 86 | +in designer.py and add an appriopriate entry using the qtplugin_factory. |
| 87 | + |
| 88 | +To check that this worked, you can simply open designer. You should see |
| 89 | +your widget added to the list. |
| 90 | + |
| 91 | + |
| 92 | +Stylesheets |
| 93 | +----------- |
| 94 | +For the widget to properly display its state, it needs an entry in the stylesheet. |
| 95 | +For widgets that are exceedingly simple to existing widgets, this might just |
| 96 | +involve copying and pasting existing entries in the stylesheet, and editing the |
| 97 | +copy to refer to your new widget. This is appropriate for adding a new valve type |
| 98 | +for example. |
| 99 | + |
| 100 | +In other cases, you'll need to do involved testing to figure out what stylesheet |
| 101 | +gives the look and feel you want for the widget, and make sure this ends up in |
| 102 | +the master stylesheet. |
| 103 | + |
| 104 | +The master stylesheet is held in the vacuumscreens repo. If it has not moved, |
| 105 | +it can be viewed at |
| 106 | +https://github.com/pcdshub/vacuumscreens/blob/master/styleSheet/masterStyleSheet.qss |
| 107 | + |
| 108 | +To activate this stylesheet for dev use, you need to set your |
| 109 | +PYDM_STYLESHEET environment variable appropriately, e.g. |
| 110 | + |
| 111 | +.. code-block bash |
| 112 | + export PYDM_STYLESHEET=/some/path/to/my/dev/folder/vacuumscreens/styleSheet.masterStyleSheet.qss |
| 113 | +
|
| 114 | +Make sure to open a pull request with your updated stylesheet in that repo and make |
| 115 | +sure that your edits get deployed in dev/prod. |
| 116 | + |
| 117 | + |
| 118 | +The Expert Screen |
| 119 | +----------------- |
| 120 | +We typically build our expert screens out of ophyd objects using the typhos module. |
| 121 | +All the specifics of this are out of scope for this tutorial, but check out |
| 122 | +pcdsdevices for our main repository of device definitions. |
| 123 | + |
| 124 | + |
| 125 | +Documentation |
| 126 | +------------- |
| 127 | +It is important to document your new widget. |
| 128 | +See examples throughout the documentation here. |
| 129 | + |
| 130 | +There are three places to update: |
| 131 | + |
| 132 | +- In the vacuum subfolder, find the relevant file and add your widget |
| 133 | + to the most logical section |
| 134 | +- In icons.rst, extend the two reference areas with a line for the table |
| 135 | + and the class-matching icon png name. The icon pngs are created |
| 136 | + automatically, so make sure your icon is importable from the top-level |
| 137 | + pcdswidgets.icons and is included in the __all__ tuple there. |
| 138 | +- Write detailed docstrings in the new classes you have added |
| 139 | + (both the icon and widget). |
| 140 | + |
| 141 | + |
| 142 | +Testing |
| 143 | +------- |
| 144 | +Your widget will automatically be tested if imported in the __all__ tuple |
| 145 | +of the vacuum submodule. Make sure to import your new widget in __init__.py |
| 146 | +there and include it in the __all__ tuple. |
| 147 | + |
| 148 | +This will catch basic issues only. |
| 149 | + |
| 150 | +You should also test your widget on real devices to make sure the behavior is |
| 151 | +correct. |
0 commit comments