Simple Qt GUI

There are multiple ways to design graphical user interfaces (GUIs) for python applications.

  • PyQt
  • TKinter
  • Kivy
  • wxPython
  • PySimpleGUI
  • PyForms
  • Wax

One of the challenges that I face when designing GUIs, is how hard it becomes to follow code when application code and GUI code are mixed together. Moreover, if I want to change how the GUI looks later in a project, or add new functionalities, it can be tough to adjust the code accordingly.

Note: It might not be a good idea to change a GUI in a project after you wrote a bunch of application code. Make sure that the GUI design pretty much complete before you write any application code, but sometimes changes might need to happen.

For the majority of the GUI interfaces listed above, this “mixture” is inevitable, but this article is going to show how we can use PyQt to separate the application code from the GUI code, in a way that allows the developer to accommodate changes in a GUI or adding new functionalities later in a project, keeping the code “clean” and separated.

If you don’t have Qt Creator IDE installed, I recommend installing it first. Qt IDE for open source development is free and available on this link.

  • Open Qt Creator and create a “new file”
  • Select “Qt” from “Files and Classes”
  • Select “Qt Designer Form”
  • Press “Choose…”
  • Select “Main Window” from “templates\forms”
  • Press “Next”
  • Name your ui file accordingly
  • Save the ui file in the same folder as your python project
  • Press “Next” and then “Finish”
  • Everything is ready to start designing your GUI.

If you are not familiar designing GUIs with IDE’s similar to Qt Creator, the learning curve can be a bit overwhelming at first. However, spending some time reading [Ref 1] first, and then complement that reading with some Qt for Python Examples from [Ref 2] and [Ref 4].

There are plenty of videos on YouTube that can help with your learning too. Codemy.com YouTube channel (Link) is a good resource to follow. The majority of the videos in Codemy.com are done for PyQt5, and I will be using PyQt6. For the majority of the GUIs that I normally do, there is no difference on using PyQt5 or PyQt6, however I will leave the differences between these two versions here.

I designed a simple GUI that has the following components:

  • textEdit to input some text
  • pushButton that will have some functionality defined later
  • the statusbar and menubar are included by default on the GUI

Everything done with Qt Creator gets saved under that ui file (xml format) created in step 1. This ui file contains the GUI code that would normally be written in your python code.

The last step is to integrate the ui file with the rest of your python code. In your python IDE, make sure that you install PyQT6 python package (Link) before continuing with this section.

The basic code to call your ui file in your python code is the following:

import sys
from PyQt6 import QtCore, QtGui, QtWidgets, uic
from PyQt6.QtWidgets import QApplication


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):

        super().__init__(*args, **kwargs)
        uic.loadUi("simpleWindow.ui", self)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec())

Let’s include some simple application code by including a callback function to the pushButton component.

import sys
from PyQt6 import QtCore, QtGui, QtWidgets, uic
from PyQt6.QtWidgets import QApplication


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Load ui File
        uic.loadUi("simpleWindow.ui", self)

        # Callback Functions
        self.pushButton.clicked.connect(self.pushButton_clicked)

    #  --------------------------------
    #  pushButton Callback Function
    #  --------------------------------
    def pushButton_clicked(self):
        text = self.textEdit.toPlainText()

        if text == "":
            self.statusBar().showMessage("Text Edit Empty...")
        else:
            self.statusBar().showMessage(text)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec())

Notice on how the application code and the GUI code aren’t mix together, which makes it easier to follow the application code.

At last, let’s show how to include a new component in the GUI and show how that process doesn’t disrupt the application code done so far.

  • First, go to Qt Creator and add a new button. I resized the first pushButton and added a pushButton_clear.
  • Save the file.
  • Go to your python code and add a new functionality for this new button. In my case, if pushButton_clear is pressed, it will clear the textEdit box.
import sys
from PyQt6 import QtCore, QtGui, QtWidgets, uic
from PyQt6.QtWidgets import QApplication


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # Load ui File
        uic.loadUi("simpleWindow.ui", self)

        # Callback Functions
        self.pushButton.clicked.connect(self.pushButton_clicked)
        self.pushButton_clear.clicked.connect(self.pushButton_clear_clicked)

    #  --------------------------------
    #  pushButton Callback Function
    #  --------------------------------
    def pushButton_clicked(self):
        text = self.textEdit.toPlainText()

        if text == "":
            self.statusBar().showMessage("Text Edit Empty...")
        else:
            self.statusBar().showMessage(text)

    #  --------------------------------
    #  pushButton_clear Callback Function
    #  --------------------------------
    def pushButton_clear_clicked(self):
        self.textEdit.setPlainText("")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec())

Hopefully this example shows how easy it is to keep the application code and GUI code separate from each other, making code development with GUI less overwhelming when things start getting more complex.

Other