Events and signals for PyQT learning

Events and Signals

event

All applications are event-driven. Most of the events are generated by the user's behavior, of course, there are other ways to generate events, such as network connections, window managers or timers. When the application's exec_() method is called, the application will enter the main loop, which will monitor and dispatch events.

In the event model, there are three roles:

  • event source
  • event
  • event target

An event source is an object whose state has changed. Events are things that change the state of this object. The event target is the target that the event wants to act on. The event source binds the event handler, and then acts on the event target.

PyQt5 has a signal and slot mechanism for event handling. Signals and slots are used for communication between objects. When an event is triggered, a signal occurs, and the slot is used to be called by Python (equivalent to a handle? This word is also disgusting, it is equivalent to the binding function of the event). The slot can only be called when the event is triggered.

Signals & slots

The following is a demonstration of signal & slot

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

In this example, we connect a signal
of a QSlider to a slot of a QLCDNumber. 

Author: Jan Bodnar
Website: zetcode.com 
Last edited: January 2017
"""

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


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_())

QtGui.QLCDNumberIn the above example, the sum module is displayed QtGui.QSlider, and we can drag the slider to make the number change accordingly.

sld.valueChanged.connect(lcd.display)

Here is to bind the change of the slider to the change of the number.

senderIt is the sender of the signal, receiverthe receiver of the signal, slotand the response that should be made to this signal.

Program display:

Refactor event handlers

In PyQt5, event handlers are often overridden (i.e. with their own overrides that come with the library).

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

In this example, we reimplement an 
event handler. 

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

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

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.Key_Escape:
            self.close()


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

In this example, we replaced the event handler function keyPressEvent().

def keyPressEvent(self, e):

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

At this time, if you press the ESC key, the program will exit.

Program display:

This is just a frame, there is nothing, so it will not be displayed.

event object

The event object is an object that uses python to describe a series of properties of the event itself.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

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

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

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()
        grid.setSpacing(10)

        x = 0
        y = 0

        self.text = "x: {0},  y: {1}".format(x, y)

        self.label = QLabel(self.text, self)
        grid.addWidget(self.label, 0, 0, Qt.AlignTop)

        self.setMouseTracking(True)

        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_())

In this example, we display the X and Y coordinates of the mouse in a component.

self.text = "x: {0},  y: {1}".format(x, y)

self.label = QLabel(self.text, self)

XY coordinates are displayed in QLabelthe component

self.setMouseTracking(True)

Event tracking is not enabled by default, and mouse click events will be tracked only after it is enabled.

def mouseMoveEvent(self, e):

    x = e.x()
    y = e.y()

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

eRepresents an event object. Inside there is the event object where we fire the event (mouse move). x()and y()method to get the x and y coordinates of the mouse, and then spell it into a string and output it to QLabelthe component.

Program display:

event sending

Sometimes we want to know which component sent a signal, and sender()the method in PyQt5 can handle this.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

In this example, we determine the event sender
object.

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

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, there are two buttons, and buttonClicked()the method determines which button can call sender()the method.

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

Both buttons are bound to the same slot.

def buttonClicked(self):

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

We sender()determine the event source by calling the method. The status bar shows which button was clicked.

Program display:

signal sending

QObjectInstances can send event signals. The following example sends a custom signal.

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

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

Author: Jan Bodnar
Website: zetcode.com 
Last edited: August 2017
"""

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, 290, 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_())

We created a signal called closeApp, this signal will be triggered when the mouse is pressed, event and QMainWindowbinding.

class Communicate(QObject):

    closeApp = pyqtSignal()

CommunicateThe class creates pyqtSignal()a signal for a property.

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

closeAppQMainWindowThe method binding for the signal close().

def mousePressEvent(self, event):

    self.c.closeApp.emit()

When the window is clicked, the closeApp signal is sent, and the program terminates.

Guess you like

Origin blog.csdn.net/zy_dreamer/article/details/132700577