功能介绍
- 点击左键、按 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