Joseph
Joseph

Reputation: 663

High-level structure of PyQt applications - splitting into modules and passing variables

As a PyQt application grows the mainwindow class becomes very crowded, and it is convenient to split the application into modules. In some cases distinctions as to what can be placed into a module are clear, for example a config file that is loaded into the mainwindow class, or a set of methods that take numerical inputs and give numerical outputs. However I am not sure about the murkey area in between, such as when computations are performed on varialbles and these used to generate/update widgets e.g. the toy example below where some computation is performed on mainwindow/config variables, and these are used to generate/update a widget (in my project these are more likely to be plot objects).

This works fine as is, but as my mainwindow class has grown I have begun to place functions such as 'plot_computation' in modules related to the job they perform. Having defined the function in a seperate module there are two options, to pass each individual variable needed to the method, or pass a reference to the entire mainwindow i.e. 'module.plot_computation(self)'. I have taken to the latter as it is feels neater when there are many arguments (4-5).

I was wondering how others structure their applications at the high-level, and what best practices are and if the approach I have taken is reasonable or could be optimised.

from PyQt5 import QtWidgets, QtGui

class UiMainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(UiMainWindow, self).__init__()

        # init variables
        self.x = 1
        self.y = 2
        self.data = None
        self.lineedit = None

        # set mainwindow + widgets
        self.mainwidget = QtWidgets.QWidget(self)
        self.mainwidget_gridlayout = QtWidgets.QGridLayout(self.mainwidget)
        self.setCentralWidget(QtWidgets.QWidget(self))
        self.centralWidget().setLayout(self.mainwidget_gridlayout)

        self.button = QtWidgets.QPushButton(self)
        self.mainwidget_gridlayout.addWidget(self.button)
        self.button.pressed.connect(self.plot_computation)

    def plot_computation(self):  # I have begun to move such methods into their own module
        self.data = self.do_computation(self.x, self.y)
        self.lineedit = QtWidgets.QLineEdit(self)
        self.mainwidget_gridlayout.addWidget(self.lineedit)
        self.lineedit.setText(str(self.data))

    def do_computation(self, x, y):  # this method would already be in a seperate module
        result = x + y
        return result


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    mw = UiMainWindow()
    mw.show()
    sys.exit(app.exec_())

Upvotes: 0

Views: 1007

Answers (0)

Related Questions