4.4.4. Implementation

This time the implementation is even more simple. OLDB datapoints are automatically handled by their widgets and the OLDB plugin. Similarly the MAL RR connection and requests happens without extra code.

We only need to indicate what to do with the replies.

4.4.4.1. Main Window Controller

The code is even smaller than Python Application Tutorial implementation. In the mainwindowcontroller.py several methods have been removed the code as in the design stage actions have been simplified; also example code for long running task has been removed.

An important piece of code to look at is the _init_gui(self) method. It also takes care of connecting the commandExecuted signal from the Taurus Command Buttons to the replyLineEdit widgets setText slot.

  1#!/usr/bin/env python3
  2"""
  3@file
  4@ingroup paegui
  5@copyright ESO - European Southern Observatory
  6
  7@brief DemoServiceClient GUI implementation
  8"""
  9
 10import time
 11
 12from taurus.external.qt.QtCore import QObject
 13from taurus.external.qt.QtCore import Slot
 14from taurus.external.qt.QtCore import Signal
 15from taurus.external.qt.QtCore import QMetaObject
 16from taurus.external.qt.QtWidgets import QApplication
 17from taurus.external.qt.QtWidgets import QMainWindow
 18from taurus.external.qt.QtWidgets import QWhatsThis
 19
 20from taurus.core.util.log import Logger, TraceIt
 21from CutColor import QePalettesModel
 22
 23from cut.examples.demo_service_client.mainwindow_ui import Ui_MainWindow  # WAF will automatically generated this
 24from cut.examples.demo_service_client.applicationconfiguration import ApplicationConfiguration
 25
 26
 27class MainWindowController(QMainWindow, Logger):
 28    '''
 29    Implementation of the mainwindow.ui file.
 30
 31    Since the UI file indicates that its root is a QMainWindow, then
 32    this class should also inherit from it.
 33    We should also call explicitly its parent constructors.
 34
 35    The implementation for this class also includes slots for 
 36    actions, and management of the closeEvent.
 37    '''
 38
 39    ###########################################################################
 40    #                Initialization and QMainWindow Methods                   #
 41    ###########################################################################
 42
 43    def __init__(self, configuration: ApplicationConfiguration):
 44        QMainWindow.__init__(self)
 45        Logger.__init__(self, name=QApplication.instance().applicationName())
 46        # Construction of UI
 47        self.ui = Ui_MainWindow()
 48        self.ui.setupUi(self)
 49        self._init_gui()
 50        self._configuration = configuration
 51
 52    def _init_gui(self):
 53        '''
 54        In some cases, widgets are not ready for modification until
 55         __init__ is done. This can be workaround by invoking another
 56         method at the end of __init__.
 57
 58        '''
 59        self.ui.splitter.setSizes([300,300])
 60        self._palettes_model = QePalettesModel()
 61        self.ui.menuView.addAction(self._palettes_model.colorSchemeMenu())
 62        self.ui.statusbar.addPermanentWidget(self.ui.qeHeartbeat)
 63        self.ui.qeBanner.show_info("If you want to understand more of the GUI, please click on \"What's This?\" and point to a GUI element.")
 64        self.ui.initTaurusCommandButton.commandExecuted.connect(self.ui.replyLineEdit.setText)
 65        self.ui.enableTaurusCommandButton.commandExecuted.connect(self.ui.replyLineEdit.setText)
 66        self.ui.disableTaurusCommandButton.commandExecuted.connect(self.ui.replyLineEdit.setText)
 67        self.ui.startUpdatesTaurusCommandButton.commandExecuted.connect(self.ui.replyLineEdit.setText)
 68        self.ui.stopUpdatesTaurusCommandButton.commandExecuted.connect(self.ui.replyLineEdit.setText)
 69
 70
 71    def closeEvent(self, event):
 72        '''
 73        Not to be confused with actionExit, this method is special. Instead
 74        of using signals to know when an application is closed, we can
 75        override the closeEvent method from the QApplication class, and
 76        determine here what will happen when the window is closed.
 77        In this case, we are just forwarding the event to its parent class.
 78        This is useful when disconnection from server or prevention of
 79        current work needs to be implemented.
 80
 81        :param event: Event received from Qt event pump
 82        :type event: QtCore.QEvent
 83
 84        '''
 85        self.info('Application shutting down...')
 86        QMainWindow.closeEvent(self, event)
 87
 88    ###########################################################################
 89    #                   First Tutorial Slots Implementation                   #
 90    ###########################################################################
 91
 92    @Slot()
 93    def on_actionExit_triggered(self):
 94        '''
 95        Slot that auto-connects to the actionExit.
 96
 97        actionExit is not declared in the code, but in the mainwindow.ui.
 98
 99        See: https://doc.qt.io/qt-5/designer-using-a-ui-file.html#widgets-and-dialogs-with-auto-connect
100
101        It is up to the developer to implement its behaviour. In this case
102        we call qApp.exit(), where qApp is a global reference to the
103        TaurusApplication or QApplication.
104        The actionExit must be manually triggered by the user, through a 
105        menu, toolbar button.
106        '''
107        self.info('Application shutting down...')
108        QApplication.instance().exit()
109

Every time a reply is returned from the server, this connections will put the text in the replyLineEdit widget.

And with that the implementation is done. As usual remember to configura compile and install the project using waf:

$ waf configure build install

Remember to start the server application using cutDemoService and execute cutDemoServiceClient to see the resulting GUI.

$ cutDemoService
$ cutDemoServiceClient