11. Working with the PyQt Graphics Package

The PyQt open source project (http://www.riverbankcomputing.com/software/pyqt/intro/) is provided under the GPL license and is a Python binding for the Qt cross-platform library (http://qt-project.org/). PyQt allows you to develop user interfaces.

A special build of this package is included in the Cerebro installation package.

11.1. Features of PyQt

The Cerebro application was also developed using the Qt library, so you need to consider several features of the PyQt package.

QApplication — an application can only include one instance of the QApplication class, and this instance is already created by our application, so you do not need to do it again when you code using PyQt:

def show_window():
    #app = QtGui.QApplication(sys.argv) do not create!!!

    box = QtGui.QMessageBox()
    box.setText('Hello, World!')
    box.exec_()

To block the main interface use dialogs or their inheritors:

def show_dialog():
        
        from PyQt5 import QtWidgets,  QtCore

        class MyDialog(QtWidgets.QDialog): # Dialog class
                ...


        dialog = MyDialog()
        dialog.exec_() # main application interface remains blocked until the dialog window is closed

Use global objects to create windows that don’t block the main interface:

window = None

def show_window():

        global window   

        if window == None: # if a window object is not created yet, creating it
                window = QtWidgets.QLabel()

                window.setText('Displaying the window for the first time')
        else:
                window.setText('Displaying the window for the next time')
        
        window.show()

Signals and Slots - Python interpreter can not catch errors in PyQt slots, use try except construction for catching errors in slots, as otherwise an incorrect application termination can occur:

class MyWindow(QtWidgets.QWidget):
    def __init__(self):

        # ...

        self.my_button = QtWidgets.QPushButton()
        self.my_button.connect(self.my_button_click) # signal

        # ...

    def my_button_click(self): # slot
        try:
            # place your code in try catch block
        except Exception as err:
            cerebro.core.print_error('PyQt Error: ' + str(err))

Warning

PyQt has one annoying feature that is related to the inability to restart Python modules without restarting the application itself. In other words, you have to disable the button that automatically restarts Python modules and avoid using the button for a full restart of the Python interpreter, as otherwise an incorrect application termination can occur. This situation is caused by the problems of re-initializing the Python interpreter, which do not provide a workaround. Therefore, you will need to restart your application each time to apply changes in the code.