Qt - Detailed explanation of event processing

Qt event handling

1. Event basis

Events are the basic building blocks in Qt applications. They represent some specific behavior or state change. Events can be mouse clicks, keyboard input, window size changes, timer events, etc. Each event is an object, inherited from the QEvent class.

2. Common types of events

Events in Qt are divided into many types, and each type corresponds to different behaviors. The following are some common event types:
1. Keyboard event (QKeyEvent): handles the press and release events of keyboard keys.

2. Mouse event (QMouseEvent): handles mouse movement, mouse button press and release events.

3. Drag and drop events (QDragEvent and QDropEvent): Events involved in drag and drop operations with the mouse, including drag and drop.

4. Wheel event (QWheelEvent): handles the scrolling event of the mouse wheel.

5. Drawing event (QPaintEvent): Triggered when the control needs to be redrawn, used for custom drawing.

6. Timing event (QTimerEvent): Triggered when the timer expires and used to perform periodic tasks.

7. Focus event (QFocusEvent): handles the movement of keyboard focus, such as window controls gaining or losing focus.

8. Enter and leave events (QEnterEvent and QLeaveEvent): handle events when the mouse moves into or out of the window control.

9. Move event (QMoveEvent): Handle the position change event of the window control.

10. Size change event (QResizeEvent): handles the size change event of the window control.

11. Show and hide events (QShowEvent and QHideEvent): Handle the display and hide events of window controls.

12. Window event (QWindowStateChangeEvent): Handles the state change event of whether the window is the current window.

3. Event Receiver

Every class that inherits from QObject can become an event receiver, which means it can receive and handle events. Widgets such as QWidget, QMainWindow, and other controls that inherit from them are examples of event receivers.

4. Event filter

Qt allows you to intercept and handle events before they reach the receiver. This is achieved through event filters, where the event is processed by another object before reaching the target object. This is useful for global event handling or when applying the same logic to multiple objects.

5. Event processing steps

1. Select event receiver:

First, you need to determine which object will be the recipient of the event. Typically, this is a widget that inherits from QWidget or other class that inherits from QObject.

2. Rewrite the event handling function:

According to the type of event you want to handle, find the corresponding event handling function in the event receiver class and rewrite it. Each event type corresponds to a specific function, such as: keyPressEvent, mousePressEvent, paintEvent, etc.

3. Write event processing logic:

In an event handler function, you can write code logic that handles specific events. For example, in keyPressEvent you can check which key was pressed and take action if necessary.

4. Call the base class event handling function:

If you wish to pass an event to the base class for further processing after handling it, you can do so by calling the base class's event handling function. This is useful in situations where you wish to continue retaining the default behavior.

6. Three common event processing applications

1. Rewrite specific event handling functions

For example: mousePressEvent(), keyPressEvent(), paintEvent(). Such a specific event handler function

①The following is to rewrite specific keyPressEvent()functions to control the upper, lower, left and right keyboards of the keyboard.

void Widget::keyPressEvent(QKeyEvent *event)
{
    
    
    switch (event->key()) {
    
    
    case Qt::Key_Up:
        ui->label->move(ui->label->x(), ui->label->y()-4);
        break;
    case Qt::Key_Down:
        ui->label->move(ui->label->x(), ui->label->y()+4);
        break;
    case Qt::Key_Left:
        ui->label->move(ui->label->x()-4, ui->label->y());
        break;
    case Qt::Key_Right:
        ui->label->move(ui->label->x()+4, ui->label->y());
        break;
    default:
        break;
    }
}

②The following is the implementation of rewriting specific mouseMoveEvent()functions

//鼠标特殊设备,必须按下任意键 移动时才会产生鼠标移动事件
void Widget::mouseMoveEvent(QMouseEvent *event)
{
    
    
    //x():获取当前鼠标在界面的x轴坐标
    ui->label->move(event->x() - ui->label->width()/2, event->y() - ui->label->height()/2);
}

2. Rewrite all event processing functions (event())

  • 1. Any event generated by the interface is first event()processed by calling the method of the base class.
  • 2. event()Inside the function, the type of event is determined, and then Dio uses a specific event extractor of the base class to process it.
  • 3. If a derived class overrides a specific event handler, event()the virtual function rewritten by the derived class is called to implement the new function.

Note : If the derived class overrides event()the virtual function, the event generated by the interface will call event()the method overridden by the derived class in advance.

  • ① Determine the events you are interested in, implement new functions, and return true after processing
  • QWidget② For events that you are not interested in, you need to manually call the function of the base class event()for default processing and return the result of the base class processing.
bool Widget::event(QEvent *event)
{
    
    
    if(event->type() == QKeyEvent::KeyPress){
    
    
        //这里我们直接调用上面重写特定好的函数实现鼠标按下的事件
        keyPressEvent((QKeyEvent *)event);
        return true;
    }
    if(event->type() == QMouseEvent::MouseMove){
    
    
    	//这里就是直接把重写鼠标移动MouseMove事件逻辑的全部代码放到里面来
        QMouseEvent *e = (QMouseEvent *)event;
        ui->label->move(e->x() - ui->label->width()/2, e->y() - ui->label->height()/2);
        return true;
    }
    return QWidget::event(event);
}

3. Override (install on the object) event filter

The purpose of the event filter is to filter out interesting events generated on the controls of interest.

bool QObject::eventFilter(QObject *watched, QEvent *event);

watched: object of interest
event: event

installEventFilter( const QOject *obj );

Steps :

  • ①Rewrite the eventFilter function
  • ② Load the concerned control into the filter installedinstallEventFilter(this); in the current class, so that any events generated on the control will be called first eventFilter()and will not be called.event()
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    
    
    //判断该事件产生的对象是否感兴趣的控件
    if(watched == ui->label_2){
    
    
        //再次判断该控件上产生的事件是否为按兴趣的事件
        if(event->type() == QMouseEvent::MouseButtonPress){
    
    
            QMouseEvent *e = (QMouseEvent *)event;
            if(e->button() == Qt::LeftButton){
    
    
                ui->label->setStyleSheet("background-color:#aa00ff;");
                qDebug()<<"LeftButton";
            }
            if(e->button() == Qt::MiddleButton){
    
    
                ui->label->setStyleSheet("background-color:#ff00ff;");
                qDebug()<<"MiddleButton";
            }
            if(e->button() == Qt::RightButton){
    
    
                ui->label->setStyleSheet("background-color:#dd000f;");
                qDebug()<<"RightButton";
            }
            return true;
        }
        /*该控件上不感兴趣的事件,都忽略
        *return false;
        *该控件上的事件其他不该兴趣的事件交给基类处理
        *return QWidget::eventFilter(watched, event);
        */
        return QWidget::eventFilter(watched, event);
    }
    /*
     *凡是不感兴趣的控件上的事件,都交给基类来处理
     *return QWidget::eventFilter(watched, event);
     */
    return QWidget::eventFilter(watched, event);
}

There are three points to note about the return value of the event filter:
① Events that are interested in the object are returned after execution true, and events that are not interested in the object are returned false(ignored)
② Interested in events on one or several objects , other events that should not be of interest are handed over to the event() function of the base class for processing, and the returned result is used as the event processing result.

return QWidget::eventFilter(watched, event);

③All events on objects that are not of interest are also handled by the base class.

return QWidget::eventFilter(watched, event);

Guess you like

Origin blog.csdn.net/qq_57737603/article/details/132550499