Qt 2D drawing: Event handling and propagation of the graphics view framework

1. Introduction

Events in the graphics view frame are first received by the view, then passed to the scene, and then passed to the corresponding graphics item by the scene. As for the keyboard event, it will be passed to the focused graphic item. You can use the setFocusItem() function of the QGraphicsScene class or the graphic item itself to call the setFocus() function to set the focused graphic item. By default, if the scene is not focused, all keyboard events will be discarded. Graphical items in the scene get focus, and the scene gets focus automatically.

For mouse hover effects, QGraphicsScene dispatches hover events. If a graphics item can receive hover events, it will receive a GraphicsSceneHoverEnter event when the mouse enters its area. If the mouse continues to move within the area of ​​the graphic item, QGraphicsScene will send a GraphicsSceneHoverMove event to the graphic item. When the mouse leaves the area of ​​the graphics item, it will receive a GraphicsSceneHoverLeave event. Graphics items cannot receive hover events by default. You can use the setAcceptHoverEvents() function of the QGraphicsItem class to enable graphical items to receive hover events.

All mouse events will be delivered to the current mouse-grabbed graphics item. If a graphics item can receive mouse events (by default) and the mouse is pressed on it, then it will become the mouse-grabbed graphics item of the scene.

The benefits of this article, the fee to receive Qt development learning materials package, technical video, including (C++ language foundation, Qt programming introduction, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project combat, QSS, OpenCV, Quick module, interview questions, etc.) ↓↓↓↓↓↓ See below

Two, examples

Let's look at an example. Create a new empty Qt project named myView. After completion, first add a Myltem custom graphics item to this project, then declare two pure virtual functions, boundingRect() and paint(), in the myitem.h file, and then declare and define a public function and variable for setting the fill color of the graphics item, and finally add some declarations of event handling functions. After completion, the content of the myitem.h file is as follows:

#ifndef MYITEM_H
#define MYITEM_H

#include <QGraphicsItem>

class MyItem : public QGraphicsItem
{
public:
    MyItem();

    //返回要绘制图形项的矩形区域
    QRectF boundingRect() const;

    //用来执行实际的绘图操作
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                  QWidget *widget);

    //用来设置图形项填充色
    void setColor(const QColor &color) { brushColor = color; }

protected:
    //鼠标按下事件处理函数,设置被点击的图形项获得焦点,并改变光标外观
    void mousePressEvent(QGraphicsSceneMouseEvent *event);

    //键盘按下事件处理函数,判断是否是向下方向键,如果是,则向下移动图形项
    void keyPressEvent(QKeyEvent *event);

    //悬停事件处理函数,设置光标外观和提示
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);

    //右键菜单事件处理函数,为图形项添加一个右键菜单
    void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);

private:
    QColor brushColor; //画刷颜色

};

#endif // MYITEM_H

By using the variable as the color of the brush, you can dynamically specify the fill color of the graphic item. By default, the fill color of the graphic item is set to red.

Then the myitem.cpp file is modified as follows:

#include "myitem.h"
#include <QPainter>
#include <QCursor>
#include <QKeyEvent>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneContextMenuEvent>
#include <QMenu>

MyItem::MyItem()
{
    brushColor = Qt::red;

    setFlag(QGraphicsItem::ItemIsFocusable);
    setFlag(QGraphicsItem::ItemIsMovable);
    setAcceptHoverEvents(true);
}

//返回要绘制图形项的矩形区域
QRectF MyItem::boundingRect() const
{
    qreal adjust = 0.5;
    return QRectF(-10 - adjust, -10 - adjust,
                  20 + adjust, 20 + adjust);
}

//用来执行实际的绘图操作
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                   QWidget *widget)
{
    Q_UNUSED(option); //标明该参数没有使用
    Q_UNUSED(widget);

    //根据图形项是否获得焦点来使用不同颜色绘制图形项的轮廓
    if(hasFocus())
    {
        painter->setPen(QPen(QColor(255,255,255,200)));
    }
    else
    {
        painter->setPen(QPen(QColor(100,100,100,100)));
    }

    //动态指定图形项的填充色
    painter->setBrush(brushColor);
    painter->drawRect(-10, -10, 20, 20);
}

//鼠标按下事件处理函数,设置被点击的图形项获得焦点,并改变光标外观
void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Q_UNUSED(event);

    setFocus();
    setCursor(Qt::ClosedHandCursor);
}

//键盘按下事件处理函数,判断是否是向下方向键,如果是,则向下移动图形项
void MyItem::keyPressEvent(QKeyEvent *event)
{
    //实现视图的下移
    if(event->key() == Qt::Key_Down)
        moveBy(0, 10);
}

//悬停事件处理函数,设置光标外观和提示
void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    Q_UNUSED(event);

    setCursor(Qt::OpenHandCursor);
    setToolTip("I am item");
}

//右键菜单事件处理函数,为图形项添加一个右键菜单
void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    QMenu menu;
    QAction *moveAction = menu.addAction("move back");
    QAction *selectedAction = menu.exec(event->screenPos());

    if(selectedAction == moveAction)
    {
        setPos(0, 0);
    }
}
  • In the mouse press event processing function, the focus is set for the graphic item clicked by the mouse, so that the graphic item will receive the key event when the keyboard is pressed.
  • Then there is the keyboard press event processing function. If the down arrow key of the keyboard is pressed, the focused graphic item will move down. Here, the moVeBy(qreal dx, qreal dy) function is used to perform relative movement, which is to move dx horizontally and dy vertically relative to the current position. This function is often used when moving items.
  • Then there is the hover event handler. If you move the mouse cursor over a graphic item, you can see that the cursor changes appearance and a tooltip appears.
  • Then there is the right-click menu event. When you right-click on a graphic item, a menu will pop up. If the menu is selected, the graphic item will move to the origin of the scene.

Then the myview.h file is modified as follows:

#ifndef MYVIEW_H
#define MYVIEW_H

#include <QGraphicsView>

class MyView : public QGraphicsView
{
    Q_OBJECT
public:
    explicit MyView(QWidget *parent = 0);

protected:
	//键盘按下事件处理函数
    void keyPressEvent(QKeyEvent *event);

signals:

public slots:

};

#endif // MYVIEW_H

Then the myview.cpp file is modified as follows:

#include "myview.h"
#include <QKeyEvent>

MyView::MyView(QWidget *parent) :
    QGraphicsView(parent)
{
}

//键盘按下事件处理函数
void MyView::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
        //数字“-”键
        case Qt::Key_Plus :
            scale(1.2, 1.2);
        break;

        //数字“+”键
        case Qt::Key_Minus :
            scale(1 / 1.2, 1 / 1.2);
        break;

        //右方向键
        case Qt::Key_Right :
            rotate(30);
        break;
    }

    QGraphicsView::keyPressEvent(event);
}

Different keys are used here to implement operations such as zooming and rotating the view. It must be noted that the keyPressEvent() function of the QGraphicsView class must be called at the end of the event processing function of the view, otherwise the event will no longer be received in the scene or graphic item.

Finally modify the main.cpp file and change its content as follows:

#include <QApplication>
#include "myitem.h"
#include "myview.h"
#include <QTime>

int main(int argc,char* argv[ ])
{
    QApplication app(argc,argv);

    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));

    QGraphicsScene scene;
    scene.setSceneRect(-200, -150, 400, 300);
    
    for(int i = 0; i < 5; ++i) 
    {
        MyItem *item = new MyItem;
        item->setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
        item->setPos(i * 50 - 90, -50);
        scene.addItem(item);
    }

    MyView view;
    view.setScene(&scene);
    view.setBackgroundBrush(QPixmap("../myView/background.png"));
    view.show();

    return app.exec();
}

Here 5 graphics items are added to the scene, random colors are set for them, and then they are arranged in a row. The view can be zoomed in and out using the "+" and "-" keys on the keyboard, and the right arrow key can be used to rotate the view.

3. Effect

Execute the program, the initial effect is as follows:

 

After pressing the right arrow key, after rotating the view:

 

After the mouse drags the graphic item:

 

The article is transferred from the blog garden (fengMisaka): Qt 2D drawing six: event processing and propagation of the graphics view framework

The benefits of this article, the fee to receive Qt development learning materials package, technical video, including (C++ language foundation, Qt programming introduction, QT signal and slot mechanism, QT interface development-image drawing, QT network, QT database programming, QT project combat, QSS, OpenCV, Quick module, interview questions, etc.) ↓↓↓↓↓↓ See below 

Guess you like

Origin blog.csdn.net/QtCompany/article/details/131859556