Introduction to PyQt6 and PySide6, commonly used libraries for Python development GUI Part 3: Explanation of interaction and communication methods

Introduction to PyQt6 and PySide6, commonly used libraries for Python development GUI Part 3: Explanation of interaction and communication methods

In PyQt6 and PySide6, events and signals are two different concepts. They are both mechanisms used in the Qt framework to handle different types of application response. Simply put, events are a direct response to user interaction or changes in system state, while signals and slots are a mechanism that allows communication between objects. In PyQt6 and PySide6 applications, the rational use of event and signal mechanisms is crucial to creating responsive and clearly structured user interfaces.

Events are triggered by user behavior (such as mouse clicks, key presses, etc.) or the system (such as timer timeout, network data arrival, etc.). Events are usually handled automatically by Qt's event system, but you can also customize the processing logic by overriding the event handler. For example, if you want to customize the painting behavior of a window component, you might override the paintEvent method.

A signal is a notification that a Qt object can send out, indicating that an action has occurred or that a state has changed. Other objects can respond to these notifications by connecting slots to these signals. This signal and slot mechanism is the core feature of Qt, which enables loosely coupled communication between objects. For example, a button (QPushButton) has a clicked signal. When the user clicks the button, this signal will be emitted. If there are slot functions connected to this signal, then these slot functions will be called.

Events are based on inheritance and overwriting, and specific responses are achieved by overriding event processing methods; events are passed to the corresponding objects through the event queue, and are processed by the object's event processing functions (such as mousePressEvent(), keyPressEvent(), etc.) for processing. If you need to customize event handling, you can do so by overriding the object's event handling function.

The communication mechanism of signals and slots is an implementation of the Observer Pattern or publish-subscribe pattern. Signals and slots provide a more advanced, decoupled way to handle communication between objects. An object does not need to know who the receiver of the signal is, it only needs to send the signal.

When a specific event occurs, the object emits a signal, which can be connected to one or more slot functions. The slot function is the function that actually handles the signal. The connection between signals and slots can span different objects, that is, a signal of one object can be connected to a slot function of another object.

Event _

Events are a core concept in Qt, used to handle user interactions. They represent things that happen in the application, such as mouse clicks, key presses, window movements, etc. Whenever these things happen, Qt creates an event object (usually an instance of the QEvent class or its subclass) and sends it to the corresponding component for processing. Components can respond to these events by overriding specific event handling functions (such as mousePressEvent(), keyPressEvent(), etc.).

Events are usually processed and distributed by Qt's event loop (Event Loop). They are synchronous, which means that when an event occurs, the relevant event handling function will be called immediately.

Events are usually processed and dispatched by Qt's event loop. Whenever the user interacts with the interface, such as moving the mouse or tapping the keyboard, an event is created and added to the event queue. The event loop then processes these events and dispatches them to the appropriate event handler.

Event Handler

An event handler is a function or method that responds to a specific event. In PyQt6 and PySide6, the QWidget class and its subclasses have a series of event handlers that can be rewritten to implement custom event handling logic. For example, if you want to customize the painting behavior of a widget, you can override its paintEvent() method.

event purpose

  1. User interaction : Events allow applications to respond to various user interactions, such as clicks, drags, scrolls, etc.
  2. Window management : Events are used to handle window changes, such as resizing, minimizing, closing, etc.
  3. System notification : Events can also be system-level, such as timer expiration, network data arrival, etc.
  4. Custom behavior : Through custom events and event handlers, developers can implement specific functions and behaviors.

In PyQt6 and PySide6, events are automatically generated by the Qt framework and delivered to the corresponding control (widget). If you want to customize or handle a specific event, you need to override the corresponding event handling method in your control class. For example, if you want to handle keyboard press events, you need to override the keyPressEvent method.

Example

Here is a simple example using the PyQt6 library to demonstrate how to handle mouse click events:

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Event Example")
        
        button = QPushButton("Click me!", self)
        button.clicked.connect(self.button_clicked)
    
    def button_clicked(self):
        print("Button clicked!")

    def keyPressEvent(self, event):
        if event.key() == Qt.Key.Key_Escape:
            print("Escape key pressed!")

app = QApplication([])
window = MainWindow()
window.show()
app.exec()

This is just a simple example. In the example, a main window class MainWindow is created that inherits from QMainWindow. In the window, we added a button and connected its click event to the button_clicked method. When the button is clicked, the button_clicked method is called and "Button clicked!" is printed.

A simple example using the PySide6 library to demonstrate how to handle mouse click events. It is similar to PyQt6. Now use PySide6 to implement the above code. Pay attention to the first two lines:

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Event Example")
        
        button = QPushButton("Click me!", self)
        button.clicked.connect(self.button_clicked)
    
    def button_clicked(self):
        print("Button clicked!")

    def keyPressEvent(self, event):
        if event.key() == Qt.Key.Key_Escape:
            print("Escape key pressed!")

app = QApplication([])
window = MainWindow()
window.show()
app.exec()

Signal _

Signal is another core concept of Qt. It is a mechanism to achieve communication between objects, especially used to achieve loose coupling in event-driven programming. When the state of an object changes, it can send out a signal, and other objects can respond to this signal through the slot function (Slot).

The signal and slot mechanism is asynchronous. When a signal is emitted, it does not call the slot function immediately. Instead, the signal is put into a queue and then handled at the appropriate time in the event loop. This allows applications to handle different signals at different points in time without blocking the current operation.

Events and signals are indeed two different concepts, but they are both mechanisms used by the Qt framework to handle different types of communication in applications.

the difference

  • Events are about things that happen inside the application, usually user interactions or system notifications.
  • Signals are a way of communication between objects, used to notify other objects that an action has occurred or that a certain state has changed.

In actual use, you may see events and signals being used at the same time. For example, when a button is clicked, it will first receive a mouse click event, and then it may emit a clicked signal. This signal can be connected and processed by any other object that cares about the click action of the button.

In summary, events and signals exist in both PyQt6 and PySide6. They are two different mechanisms, used to handle internal user interface events and implement communication between objects respectively.

Slot is a key concept in the signal and slot mechanism. A slot can be understood as a function that receives a signal. When a signal is emitted, all slot functions connected to this signal will be called.

A slot function can be any callable Python function or object method that responds to a signal. When you design a graphical user interface (GUI), you define slot functions to perform specific tasks, such as updating interface elements, processing data, or communicating with other components.

How signals and slots work:

  1. Signal : When an event occurs or the object's state changes, the object emits a signal.
  2. Slot : This is a function or method that is designed to respond to a signal. You can connect a signal to one or more slots.
  3. Wiring : In code, you will wire signals and slots. When the signal is emitted, the connected slot function is called.

Slot functions are not event handlers, but they can be used as part of event handling. Event handlers are typically functions that are called in response to specific events (such as mouse clicks, key presses, etc.). Slot functions are functions that respond to signals (triggered by events or other conditions).

Signals and slots are a communication mechanism in Qt that allow decoupled communication between objects. When an event occurs, such as a button being clicked, a signal is emitted. Then, any slot function connected to the signal will be called.
In PyQt6, use pyqtSignal to create a signal, in PySide6, you use Signal.

Example

Suppose you have a button (QPushButton) and when the user clicks the button, you want to update the text of the label (QLabel). You can do this, look at the main code first:

# Assume this is a slot function
def update_label():
    label.setText("The button was clicked")

The PyQt6 and PySide6 implementations are given below.

The difference between the two is not big, which is reflected in: the prefix of the from statement is different. The signal in PyQt6 uses pyqtSignal, while the signal in PySide6 uses Signal.

Code implemented by PyQt6

☆Use the clicked signal implementation provided by the system, the code is as follows:

from PyQt6.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("示例")

        layout = QVBoxLayout()

        self.button = QPushButton("点击我")
        self.label = QLabel("初始文本")

        # 将按钮的 clicked 信号连接到槽函数
        self.button.clicked.connect(self.update_label)

        layout.addWidget(self.button)
        layout.addWidget(self.label)

        self.setLayout(layout)

    # 创建槽函数
    def update_label(self):
        self.label.setText("按钮被点击了")


# 创建应用程序对象
app = QApplication([])

# 创建自定义窗口对象
window = MyWindow()

# 显示窗口
window.show()

# 运行应用程序
app.exec()

In this example, update_label is a slot function that is connected to the clicked signal of the button (using the clicked signal of the system-provided QPushButton class). When the button is clicked, the clicked signal is emitted, then the update_label function is called, and the text of the label is updated.

In summary, slots are functions or methods used to respond to signals in the signal and slot mechanism. They are not event handlers, but can be used in the event handling process.

The above example uses the clicked signal of the QPushButton class provided by the system. The system provides many predefined signals, which are defined in various components of Qt. The clicked signal is a built-in signal of the QPushButton class, which is emitted when the button is clicked.

☆Using custom signals to achieve:

You can also customize signals to emit your own signals in specific scenarios and connect them to custom slot functions. Here is an example of implementing the above using a custom signal:

from PyQt6.QtCore import pyqtSignal
from PyQt6.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget

class MyWindow(QWidget):
    button_clicked = pyqtSignal() # 定义了一个名为button_clicked的自定义信号
    
    def __init__(self):
        super().__init__()
        self.setWindowTitle("示例")

        layout = QVBoxLayout()

        self.button = QPushButton("点击我")
        self.label = QLabel("初始文本")

        #将按钮的clicked信号连接到emit_button_clicked方法
        self.button.clicked.connect(self.emit_button_clicked) 

        layout.addWidget(self.button)
        layout.addWidget(self.label)

        self.setLayout(layout)

    # emit_button_clicked方法
    def emit_button_clicked(self):
        self.label.setText("按钮被点击了")
        self.button_clicked.emit()


# 创建应用程序对象
app = QApplication([])

# 创建自定义窗口对象
window = MyWindow()

# 创建槽函数
def update_label():
    window.label.setText("按钮被点击了")

#将button_clicked信号连接到update_label槽函数
window.button_clicked.connect(update_label)

# 显示窗口
window.show()

# 运行应用程序
app.exec()

In this example, we define a custom signal called button_clicked, which is an instance of the pyqtSignal class. When the button is clicked, we emit this custom signal by calling the emit() method.

In the main function, we create an update_label function to update the text of the label. We connect the button_clicked signal to the update_label slot function so that when the custom signal is emitted, the slot function will be triggered.

By using a custom signal, we can emit a signal when the button is clicked and connect it to a custom slot function to achieve the desired functionality. This approach provides greater flexibility, allowing you to define and use custom signals as needed.

Code implemented by PySide6

☆Use the clicked signal implementation provided by the system, the code is as follows:

from PySide6.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("示例")

        layout = QVBoxLayout()

        self.button = QPushButton("点击我")
        self.label = QLabel("初始文本")

        # 将按钮的 clicked 信号连接到槽函数
        self.button.clicked.connect(self.update_label)

        layout.addWidget(self.button)
        layout.addWidget(self.label)

        self.setLayout(layout)

    # 创建槽函数
    def update_label(self):
        self.label.setText("按钮被点击了")


# 创建应用程序对象
app = QApplication([])

# 创建自定义窗口对象
window = MyWindow()

# 显示窗口
window.show()

# 运行应用程序
app.exec()

☆Using custom signals to achieve:

from PySide6.QtCore import Signal
from PySide6.QtWidgets import QApplication, QLabel, QPushButton, QVBoxLayout, QWidget

class MyWindow(QWidget):
    button_clicked = Signal() # 定义了一个名为button_clicked的自定义信号
    
    def __init__(self):
        super().__init__()
        self.setWindowTitle("示例")

        layout = QVBoxLayout()

        self.button = QPushButton("点击我")
        self.label = QLabel("初始文本")

        #将按钮的clicked信号连接到emit_button_clicked方法
        self.button.clicked.connect(self.emit_button_clicked) 

        layout.addWidget(self.button)
        layout.addWidget(self.label)

        self.setLayout(layout)

    # emit_button_clicked方法
    def emit_button_clicked(self):
        self.label.setText("按钮被点击了")
        self.button_clicked.emit()


# 创建应用程序对象
app = QApplication([])

# 创建自定义窗口对象
window = MyWindow()

# 创建槽函数
def update_label():
    window.label.setText("按钮被点击了")

#将button_clicked信号连接到update_label槽函数
window.button_clicked.connect(update_label)

# 显示窗口
window.show()

# 运行应用程序
app.exec()

The signal- slot mechanism and the event mechanism are two different ways of interaction and communication . It is inevitable to be vague when you first start to learn and understand them. Here is some further analysis.

In Qt C++, PyQt6 and PySide6, the signal-slot mechanism and event mechanism are very commonly used, and they each have different usage scenarios and advantages. They can be mixed, and this mix is ​​very common because they each solve different problems.

The signal-slot mechanism is mainly used for communication between objects. When an event occurs, such as the user clicking a button, the button object emits a signal. This signal can be connected to any slot function, no matter which object the slot function belongs to, as long as their parameter types are compatible. In this way, the sender of the signal does not need to know the specific situation of the receiver, thus achieving decoupling between objects.

The event mechanism is used to handle various events in Qt applications, such as mouse clicks, keyboard keys, timer timeouts, etc. Events are usually distributed to corresponding objects by Qt's event loop, and can be handled by event handling functions overridden by these objects.

In Qt C++, PyQt6 and PySide6, the signal-slot mechanism and event mechanism are very commonly used, and they each have different usage scenarios and advantages.

Signal- slot mechanism:

The signal-slot mechanism is one of the core features of the Qt framework, which is used for communication between objects.

  • The signal-slot mechanism is a communication mechanism unique to Qt that allows decoupled communication between objects.
  • A signal is a message that an object can emit to indicate that an event has occurred.
  • A slot is a function that can be triggered by a signal, which can be any callable block of code.
  • The connection between signals and slots is established through QObject's connect() function.

The signal-slot mechanism is implemented simply by defining signals and slots in an object (usually a subclass of QObject), and then connecting the signals and slots. When the signal is emitted, the slot connected to it will be called. .

Application scenarios: Suitable for handling user interface events, communication between objects, cross-thread communication, etc. In GUI programming, it is often used to handle user interaction events such as button clicks and text box input.

When developing GUI applications, you will frequently use the signal-slot mechanism to respond to user operations, such as button clicks, menu selections, etc. The advantages of the signal-slot mechanism are:

  • Decoupling:  The signal sender and slot receiver do not need to know the existence of each other.
  • Simplicity:  Complex communication mechanisms can be established with a simple connect() call.
  • Flexibility:  A signal can be connected to multiple slots, and a slot can receive multiple signals.
  • Cross-thread communication:  The signal-slot mechanism can be safely used in a multi-threaded environment, and Qt will handle the synchronization problem between threads.

In the design pattern, the signal-slot mechanism embodies the observer pattern, which is very important in GUI programs.

Event mechanism:

The event mechanism is the basis for handling user interaction and system events.

  • The event mechanism is a more general programming model that exists not only in Qt, but also in many other programming frameworks.
  • Events are generated by an application or system to indicate a change in state or the occurrence of user interaction.
  • Events are delivered through the event queue and processed by the event loop.
  • Event handling is usually done by overriding the object's event handling function (such as mousePressEvent()).

Implementation method Implementation method, simply put, the event mechanism usually consists of an event loop, an event dispatcher and an event handler. When an event occurs, the event dispatcher distributes the event to the corresponding event handler for processing.

Application scenarios: Suitable for processing various types of events such as underlying system events, hardware events, network events, etc. In cross-platform frameworks, such as Qt, wxWidgets, etc., the event mechanism is usually used to handle system-level events, such as window closing, mouse movement, etc.

The event mechanism allows programs to respond to events such as key presses, mouse movements, and window redraws. The advantages of the event mechanism are:

  • Directness:  Events are sent directly to the object and handled by the object, which makes event handling logic usually straightforward.
  • Fine-grained control:  By overriding event handling functions, you can precisely control the object's response to events.
  • Broadness:  The event mechanism is not only used for user interaction, but also for the processing of system-level events.

During development, you may need to pay attention to the following:

  • The signal- slot mechanism  is more suitable for handling communication between different objects, especially when you need to separate the behavior of UI components from business logic.
  • The event mechanism  is more suitable for handling state changes within a single object, or in response to specific events.

In actual development, you will find that both are very important, and they often need to be used at the same time. For example, you might override a window's mousePressEvent() method to handle mouse click events (event mechanism), and then emit a signal inside the method that is connected to the slot function of another object to perform further operations ( signal-slot mechanism).

The signal-slot mechanism and event mechanism are both important tools in Qt for handling communication between objects and user interaction. The signal-slot mechanism focuses more on decoupled communication between objects, while the event mechanism focuses on response processing to specific events. In practical applications, the two are often used in combination to implement complex interaction logic. For example, a button click event (event mechanism) may trigger a signal, which in turn is connected to a slot function to perform a specific operation.

Example scenario for mixed use:

  1. You might emit a custom signal in a widget's event handler (such as mousePressEvent). This signal can be connected to the slots of other objects to notify them that an event has occurred.
  2. You may be in a slot function that handles a signal, generate a new event as needed and use QCoreApplication::postEvent to add it to the event queue for later processing.
  3. In some cases, you may need to query or modify the status of other objects in the event handling function. In this case, you can interact with the slot functions of these objects by emitting signals.
  4. You can also call the update() or repaint() method in the slot function to request a redraw of the component, which will cause a paint event (paintEvent) to be sent to the event queue.

The signal-slot mechanism and the event mechanism are two different interaction and communication methods, and they are both implemented in the Qt framework.

The key to using both mechanisms is understanding their design purpose and best practices. The signal-slot mechanism is for decoupled communication between objects, while the event mechanism is for processing and responding to specific events. They work well together to create a responsive and clearly structured application.

The application scenarios of the signal-slot mechanism overlap with the application scenarios of the event mechanism. Although there is some overlap, there are some differences in design between the signal and slot mechanism and the event mechanism. They are not completely replaceable. Here are some key differences between the two.

Signal-slot mechanism:

  • Used for communication between objects.
  • It is an implementation of the Observer pattern that allows an object to notify one or more other objects that an event has occurred.
  • Signal-slot connections are established at compile time or runtime and can be connected or disconnected dynamically.
  • Signals can pass parameters to slot functions, and these parameters usually contain information about the event that triggered the signal.
  • It is suitable for realizing loosely coupled interactions between different components, such as communication between user interface controls and application logic.

Event mechanism:

  • Used to handle input (such as mouse, keyboard), timer, drawing and other events.
  • Events are distributed by Qt's event loop, and event handling functions (such as mousePressEvent, keyPressEvent) usually need to be rewritten in the target object to respond to events.
  • Event processing is synchronous, that is, once the event is dispatched, the event handling function of the target object will be executed immediately.
  • Events can be ignored or accepted, or passed to parent components for further processing.
  • Suitable for processing and responding to user interactions and system notifications.

In practical applications, the appropriate mechanism is usually selected based on specific needs. For example, if you need to handle user click events, you might override mousePressEvent. If you need to pass data or notifications between different components, you might use the signal-slot mechanism. In complex applications, both mechanisms are often used together to achieve more flexible interaction and better code organization.

PySide6 official related information

https://doc.qt.io/qtforpython/tutorials/basictutorial/signals_and_slots.html

https://doc.qt.io/qtforpython-6/PySide6/QtCore/QEvent.html#qevent

PyQt6 official related information

https://www.riverbankcomputing.com/static/Docs/PyQt6/signals_slots.html

https://www.riverbankcomputing.com/static/Docs/PyQt6/api/qtcore/qevent.html

Supongo que te gusta

Origin blog.csdn.net/cnds123/article/details/135190542
Recomendado
Clasificación