Title: Direct load of .ui files
SEP: 11
State: ACCEPTED
Date: 2014-07-24
Drivers: Tiago Coutinho coutinho@esrf.fr
URL: https://sourceforge.net/p/sardana/wiki/SEP11
License: http://www.jclark.com/xml/copying.txt
Abstract:
Currently, some taurus widgets are designed using the QtDesigner.
The resulting .ui files are transformed into python code with taurusuic4(pyuic4).
The widgets use the generated code to build themselves.
This approach has some problems. This SEP tries to solve them by directly building
the widgets with the original .ui file.
The current approach to build taurus widgets based on .ui files has some problems. This SEP proposes an alternative method to build taurus widgets from their original .ui files without having to go through the intermediate step on generating python code with the taurusuic4(pyuic4) tools.
Currently, some taurus widgets are designed using the QtDesigner. The resulting .ui files are transformed into python code with taurusuic4(pyuic4). The widgets use the generated code to build themselves. This approach as some problems:
The goal is to make taurus widgets based on .ui files usable out of the box without an intermediate generation step. Taurus becomes cleaner, less dependent on tools. It also makes it compatible with multiple Qt versions and backends.
The only foreseeable drawback is in terms of performance. If a widget based on a .ui file is instantiated multiple times in a GUI, the process of loading a .ui file is repeated for each instance of the widget. If this becomes a problem then a system to cache .ui files can be put in place (remember: premature optimization is the root of all evil)
Backward compatibility is a mandatory requirement for a successful implementation.
The SEP proposes a helper in form of a python decorator that should be used in widgets that are based on .ui files.
The helper needs to be implemented having into account the fact that many taurus widgets based on .ui files are based on the recipe:
class MyWidget(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) from .ui.ui_MyWidget import Ui_MyWidget self._ui = Ui_MyWidget() self._ui.setupUi(self) self._ui.mylabel.setText("Here I am")
The helper should have options to allow easy transition into the new system.
Here is a proposal for the API:
def UILoadable(klass=None, filename=None, path=None, with_ui=None): pass
Basic example:
@UILoadable class MyWidget(Qt.QWidget): def __init__(self, ...): self.loadUi() self.mylabel.setText("Here I am")
Another example using a new member _ui to avoid polluting the widget namespace:
@UILoadable(with_ui='_ui') class MyWidget(Qt.QWidget): def __init__(self, ...): self.loadUi() self._ui.mylabel.setText("Here I am")
Copyright (c) 2014 Tiago Coutinho
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2015-05-13
cpascual Fixed date in header to reflect acceptance date
2014-07-04 tiagocoutinho
Changed state to ACCEPTED
2014-07-04 tiagocoutinho
Added decorator without parameters example
2014-03-05 tiagocoutinho
Changed state to CANDIDATE
2014-02-24 tiagocoutinho
Initial version