Intro to PyQT (The Clean Way) : Button

We have now learnt how to create a main window, now lets check how a button works.

Button in Qt is an instance of class QPushButton.

So lets create a button.ui with QMainWindow and drag a button from layouts toolbar onto Main Window. I am setting the objectName as dont_press_me_button and it’s text attribute as Don't press me

Now let’s save this as button.ui in our ui folder

Now coming to the Python part, lets create a button.py in parent folder of ui folder where our hello_world.py is located.

Our application always has similar structure to hello_world.py except some basic differences with naming of classes.

from PyQt5 import QtCore, QtWidgets, uic
import os,sys

BASE_FOLDER = os.path.dirname(os.path.realpath(__file__))
UI_FOLDER = os.path.join(BASE_FOLDER,"ui")

main_window_ui_file = os.path.join(UI_FOLDER,"button.ui")
main_window_uic = uic.loadUiType(main_window_ui_file)[0] ## Get Ui Class (Form Class)


class ButtonMainWindow(QtWidgets.QMainWindow,main_window_uic):

    def __init__(self):
        super(ButtonMainWindow, self).__init__()
        self.setupUi(self)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = ButtonMainWindow()
    main_window.show()
    sys.exit(app.exec_())

The above is the basic skeleton of our application to test button. Now we can access the QPushButton object in our class using class attribute self.dont_press_me_button. Notice that the self.dont_press_me_button class attribute is generated using objectName which we fixed in designer.

Now how to notify Python that a button is pressed?

Qt achieves this by using Signals and Slots. Signal are, you know signals which can be emitted when an event occurs and Slots are bindings (generally a function object) to a specific signal, which gets executed when a function is called. We will discuss more on this later!

Now when a button is pressed, it emits a signal clicked. So this means QPushButton.clicked is a signal object. Now we need to connect this signal to a slot. So in our python code in ButtonMainWindow we will create a function named button_clicked which prints some text when called. So now our code looks like and button_clicked is our slot for signal we receive when button is clicked.

from PyQt5 import QtCore, QtWidgets, uic
import os,sys

BASE_FOLDER = os.path.dirname(os.path.realpath(__file__))
UI_FOLDER = os.path.join(BASE_FOLDER,"ui")

main_window_ui_file = os.path.join(UI_FOLDER,"button.ui")
main_window_uic = uic.loadUiType(main_window_ui_file)[0] ## Get Ui Class (Form Class)


class ButtonMainWindow(QtWidgets.QMainWindow,main_window_uic):

    def __init__(self):
        super(ButtonMainWindow, self).__init__()
        self.setupUi(self)
        
    def button_clicked(self):
        print("I said not to press me  >:(")

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = ButtonMainWindow()
    main_window.show()
    sys.exit(app.exec_())

Now we need to connect self.dont_press_me_button.clicked to button_clicked method of the class this can be done by passing function object to connect attribute of self.dont_press_me_button.clicked, so it looks like

self.dont_press_me_button.clicked.connect(self.button_clicked)

The above line must be executed before Signal is emitted to connect to the button_clicked function.
Our code now looks like

from PyQt5 import QtCore, QtWidgets, uic
import os,sys

BASE_FOLDER = os.path.dirname(os.path.realpath(__file__))
UI_FOLDER = os.path.join(BASE_FOLDER,"ui")

main_window_ui_file = os.path.join(UI_FOLDER,"button.ui")
main_window_uic = uic.loadUiType(main_window_ui_file)[0] ## Get Ui Class (Form Class)


class ButtonMainWindow(QtWidgets.QMainWindow,main_window_uic):

    def __init__(self):
        super(ButtonMainWindow, self).__init__()
        self.setupUi(self)
        self.dont_press_me_button.clicked.connect(self.button_clicked)

    def button_clicked(self):
        print("I said not to press me  >:(")

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    main_window = ButtonMainWindow()
    main_window.show()
    sys.exit(app.exec_())

That’s it, now run the code using python button.py and when you press the button it prints "I said not to press me >:("

Leave a Reply

Your email address will not be published.