7. Custom App/Extension

PyMoDAQ’s set of modules is a very efficient way to build a completely custom application (related to data acquisition or actuators displacement) without having to do it from scratch. Fig. 7.1 is an example of such an interface build using only PyMoDAQ’s building blocks. The corresponding script template is within the example folder.

dashboard

Fig. 7.1 A custom application build using PyMoDAQ’s modules.

Note

A generic base class CustomApp located in pymodaq.daq_utils.gui_utils can be used to build very quickly standalone Application or Dashboard extensions. The DAQ_Logger extension has been built using it as well as some examples in the example folder.

Below you’ll find the skeleton of a CustomApp subclassing the base class and methods you have to override with your App/Extension specifics:

class CustomAppExample(gutils.CustomApp):

    # list of dicts enabling a settings tree on the user interface
    params = [
        {'title': 'Main settings:', 'name': 'main_settings', 'type': 'group', 'children': [
            {'title': 'Save base path:', 'name': 'base_path', 'type': 'browsepath',
             'value': config['data_saving']['h5file']['save_path']},
            {'title': 'File name:', 'name': 'target_filename', 'type': 'str', 'value': "", 'readonly': True},
            {'title': 'Date:', 'name': 'date', 'type': 'date', 'value': QDate.currentDate()},
            {'title': 'Do something, such as showing data:', 'name': 'do_something', 'type': 'bool', 'value': False},
        ]},
    ]

    def __init__(self, dockarea, dashboard=None):
        super().__init__(dockarea)
        # init the App specific attributes
        self.raw_data = []

    def setup_actions(self):
        '''
        subclass method from ActionManager
        '''
        logger.debug('setting actions')
        self.add_action('quit', 'Quit', 'close2', "Quit program", toolbar=self.toolbar)
        self.add_action('grab', 'Grab', 'camera', "Grab from camera", checkable=True, toolbar=self.toolbar)
        logger.debug('actions set')

    def setup_docks(self):
        '''
        subclass method from CustomApp
        '''
        logger.debug('setting docks')
        self.dock_settings = gutils.Dock('Settings', size=(350, 350))
        self.dockarea.addDock(self.dock_settings, 'left')
        self.dock_settings.addWidget(self.settings_tree, 10)
        logger.debug('docks are set')

    def connect_things(self):
        '''
        subclass method from CustomApp
        '''
        logger.debug('connecting things')
        self.actions['quit'].connect(self.quit_function)
        self.actions['grab'].connect(self.detector.grab)
        logger.debug('connecting done')

    def setup_menu(self):
        '''
        subclass method from CustomApp
        '''
        logger.debug('settings menu')
        file_menu = self.mainwindow.menuBar().addMenu('File')
        self.affect_to('quit', file_menu)
        file_menu.addSeparator()
         logger.debug('menu set')

    def value_changed(self, param):
        logger.debug(f'calling value_changed with param {param.name()}')
        if param.name() == 'do_something':
            if param.value():
                self.settings.child('main_settings', 'something_done').setValue(True)
            else:
                self.settings.child('main_settings', 'something_done').setValue(False)

        logger.debug(f'Value change applied')

"""
All other methods required by your Application class
"""

In a few lines of codes, you’ll get an application running. For the available Parameter available for your settings_tree, see Settings.