QT中使用rubberband橡皮筋等方法进行选中多个物体

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sty945/article/details/86591713

功能介绍

  • 点击左键、按 Shift 键可以单选,按下 Ctrl 可进行多选。
  • 选中时候点击右键,可以选择隐藏物体,归位
  • 移动:点击左键,选择 item,然后移动鼠标

代码介绍

myitem.h/cpp 图形项

myitem.h

#ifndef MYITEM_H
#define MYITEM_H

#include <QGraphicsItem>

class MyItem : public QGraphicsItem
{
public:
    MyItem();
    ~MyItem();
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    void setColor(const QColor &color){brushColor = color;};

private:
    QColor brushColor;

protected:
    void keyPressEvent(QKeyEvent *event);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void hoverEnterEvent(QGraphicsSceneMouseEvent *event);
    void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);

};

#endif // MYITEM_H

myitem.cpp

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

MyItem::MyItem()
{
    brushColor = Qt::red;
    //设置图形项可以移动
    setFlag(QGraphicsItem::ItemIsMovable);
    //设置图形项可以选择
    setFlag(QGraphicsItem::ItemIsSelectable);
    //设置接受鼠标悬停事件
    setAcceptHoverEvents(true);
}

MyItem::~MyItem()
{

}


//设置包围盒,返回图形项矩形区域
//详细信息参考:http://doc.qt.io/archives/qt-4.8/qgraphicsitem.html
QRectF MyItem::boundingRect() const
{
    //画笔宽度
    qreal adjust = 0.5;
    //因为paint函数中的矩形是以(-10,-10)为原点画出的长宽均为20的矩形
    return QRectF(-10 - adjust, -10 - adjust, 20 + adjust, 20 + adjust);
}


//执行实际的绘图操作
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    //判断是否被选中
    if (isSelected()){
        //设置轮廓为白色
        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::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Down)
    {
        moveBy(0, 10);
    }
    else if (event->key() == Qt::Key_Up)
    {
        moveBy(0, -10);
    }
    else if (event->key() == Qt::Key_Right)
    {
        moveBy(10, 0);
    }
    else if (event->key() == Qt::Key_Left)
    {
        moveBy(-10, 0);
    }
}


//鼠标按下事件处理函数,设置被点击的图形项是否被选中,并改变外观
//系统默认Ctrl+鼠标左键可实现多选
void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    //设置鼠标形状
    setCursor(Qt::ClosedHandCursor);
    if (event->button() == Qt::LeftButton)
    {
        //设置shift+鼠标左键单选
        if (event->modifiers() == Qt::ShiftModifier)
        {
            qDebug() << "item left clicked with shift key";
            setSelected(true);
        }
        else
        {
            qDebug() << "item left clicked";
            QGraphicsItem::mousePressEvent(event);
        }
    }
//	else if (event->button() == Qt::RightButton)
//	{
//		qDebug() << "item right clicked";
//	}
}

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

//右键菜单事件处理函数,为图形项添加一个右键菜单
void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    QMenu menu;
    QAction *moveAction = menu.addAction("move back");
    QAction *hideAction = menu.addAction("hide");
    QAction *showAction = menu.addAction("show");
    QAction *selectedAction = menu.exec(event->screenPos());
    //让图形项归位到场景原点
    if (selectedAction == moveAction)
    {
        setPos(0, 0);
    }
    else if (selectedAction == hideAction)
    {
         setVisible(false);
    }
    else if (selectedAction == showAction)
    {
        setVisible(true);
    }
}

myview.h/cpp场景

myview.h

#ifndef MYVIEW_H
#define MYVIEW_H
#include <QGraphicsView>

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

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);

};

#endif // MYVIEW_H

myview.cpp

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

MyView::MyView(QWidget *parent) :
    QGraphicsView(parent)
{
    //设置橡皮筋选择选项
    setDragMode(QGraphicsView::RubberBandDrag);
}

MyView::~MyView()
{

}

void MyView::mousePressEvent(QMouseEvent *event)
{
    QGraphicsView::mousePressEvent(event);
}

void MyView::mouseReleaseEvent(QMouseEvent *event)
{
    QGraphicsView::mouseReleaseEvent(event);
}

主函数

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    //设置随机种子
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));

    //设置场景
    QGraphicsScene scene;
    scene.setSceneRect(-200, -150, 400, 300);

    //随机生成5个颜色不同的矩形
    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(Qt::gray);
    //显示
    view.show();

    return a.exec();
}

结果展示

在这里插入图片描述

代码下载

https://download.csdn.net/download/sty945/10931750

参考

https://blog.csdn.net/liang19890820/article/details/53504323

猜你喜欢

转载自blog.csdn.net/sty945/article/details/86591713