PyQt5 Learning Notes (05)--Event and signals

Posted by mark_h_uk on Fri, 17 May 2019 16:24:53 +0200

The code in this article comes from zetcode.com

Events

GUI applications are event-driven, and events are generated mainly by users.
But events can also be generated through, for example, Internet links, window managers, or timers.
When we enter the main loop of the program through the exec_() method, the main loop gets the event and sends it.

In the event model, there are three participants:

event source
event object
event target

Events occur when the event source state changes
event object encapsulates the changed state in the event source
Event target event target is the object that you want to notify

PyQt5 has a unique signal and slot mechanism to handle events:
When an event occurs, a signal is generated, and when the connection signal is sent, the slot is invoked.

Signals and slots

#!/usr/bin/python3

"""
This program will create a signal
of a QSlider to a slot of a QLCDNumber
"""

import sys
from PyQt5.QtWidgets import QWidget, QApplication, QLCDNumber, QSlider, QVBoxLayout
from PyQt5.QtCore import Qt


class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        lcd = QLCDNumber(self)
        sld = QSlider(Qt.Horizontal, self)

        vbox = QVBoxLayout()
        vbox.addWidget(lcd)
        vbox.addWidget(sld)

        self.setLayout(vbox)
        sld.valueChanged.connect(lcd.display)

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Signal and slot')
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

The above code shows QtGui.QLCDNumber and QtGui.QSlider, and as we drag and drop the slider, the number changes.

sld.valueChanged.connect(lcd.display)


Reimplementing event handler

The following code implements the Esc key exit program

#!/usr/bin/python3

"""
In this example, we reimplement an event handler.
"""

import sys
from PyQt5.QtWidgets import QWidget, QApplication
from PyQt5.QtCore import Qt


class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Event Handler')
        self.show()

    def keyPressEvent(self, e):
        if e.key() == Qt.Kye_Escape:
            self.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

We re-implement the keyPressEvent() event handler

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()

Event object

Event objects are attributes that contain many descriptions of events. Event objects are specific to the type of events generated.
This example shows the coordinate position of the mobile mouse.

#!/usr/bin/python3

"""
In this example, we display the x and y
coordinates of a mouse pointer in a label widget.
"""

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication, QGridLayout, QLabel


class Example(QWidget):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        grid = QGridLayout()

        x = 0
        y = 0

        self.text = "x: {0}, y: {1}".format(x, y)
        self.label = QLabel(self.text, self)    #  (x,y) coordinates are displayed in the QLabel control

        grid.addWidget(self.label, 0, 0, Qt.AlignTop)    #  Place the control in the upper left corner
        self.setMouseTracking(True)    #  The default is to turn off, and the event generates a signal when it is turned on.
        self.setLayout(grid)

        self.setGeometry(300, 300, 350, 200)
        self.setWindowTitle('Event Object')
        self.show()

    def mouseMoveEvent(self, e):
        x = e.x()
        y = e.y()
        text = "x: {0}. y: {1}".format(x, y)
        self.label.setText(text)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


Event sender

sender() method knows which control sends a signal

#!/usr/bin/python3

"""
In this example, we determine the event sender object.
"""

import sys
from PyQt5.QtWidgets import QMainWindow, QPushButton, QApplication


class Example(QMainWindow):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        btn1 = QPushButton("Button 1", self)
        btn1.move(30, 50)

        btn2 = QPushButton("Button 2", self)
        btn2.move(150, 50)

        btn1.clicked.connect(self.buttonClicked)
        btn2.clicked.connect(self.buttonClicked)

        self.statusBar()

        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Event sender')
        self.show()

    def buttonClicked(self):
        sender = self.sender()
        self.statusBar().showMessage(sender.text() + ' was pressed')


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

In this example, two buttons are shown, and when 1 or 2 is pressed, the status bar displays a prompt message.

sender = self.sender()

Know the signal source by sender()


Emitting signals

Objects created from QObject can send signals

#!/usr/bin/python3

"""
In this example, we show how to emit a custom signal.
"""

import sys
from PyQt5.QtCore import pyqtSignal, QObject
from PyQt5.QtWidgets import QMainWindow, QApplication


class Communicate(QObject):
    closeApp = pyqtSignal()


class Example(QMainWindow):

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.c = Communicate()
        self.c.closeApp.connect(self.close)

        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle('Emit Signal')
        self.show()

    def mousePressEvent(self, event):
        self.c.closeApp.emit()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

Signals are created by pyqtSignal(), and custom closeApp signals are connected to the close() slot of QMainWindow.

        self.c = Communicate()
        self.c.closeApp.connect(self.close)

We define the mouse click event, and when we click the mouse, the program exits.

    def mousePressEvent(self, event):
        self.c.closeApp.emit()

Topics: Qt Mobile