说明
在使用Qt的图形视图框架实现功能时,一般会在其基础上进行自定义功能实现。
如:滚轮对场景的缩放,鼠标拖动场景中的项,以及可以在场景中进行右键操作等。
示例
myitem
为自定义QGraphicsItem,实现了边框、重绘事件、鼠标悬停、按键、右键菜单等功能。
myitem.h
#ifndef MYITEM_H
#define MYITEM_H
#include <QGraphicsItem>
class MyItem : public QGraphicsItem
{
public:
MyItem();
// 边框
virtual QRectF boundingRect() const override;
// 重绘事件
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget) override;
// 设置笔刷
inline void setColor(const QColor &color) {brushColor = color;}
protected:
// 鼠标按下函数,设置被点击的图形项得到焦点,并改变光标外观
virtual void keyPressEvent(QKeyEvent *event) override;
// 键盘按下函数,判断是不是向下方向键,若是是,则向下移动图形项
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
// 悬停事件函数,设置光标外观和提示
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) override;
// 右键菜单函数,为图形项添加一个右键菜单
virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) override;
private:
QColor brushColor; // 笔刷颜色
};
#endif // MYITEM_H
myitem.cpp
#include "myitem.h"
#include <QPainter>
#include <QCursor>
#include <QKeyEvent>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneContextMenuEvent>
#include <QMenu>
#define WIDTH 40
#define HEIGHT 40
#define POS 20
MyItem::MyItem()
{
brushColor = Qt::black;
setFlag(QGraphicsItem::ItemIsFocusable);
setFlag(QGraphicsItem::ItemIsMovable);
setAcceptHoverEvents(true);
}
QRectF MyItem::boundingRect() const
{
qreal adjust = 0.5; // 返回上下左右+0.5个像素
return QRectF(-POS - adjust, -POS - adjust,
WIDTH + adjust, HEIGHT + adjust);
}
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *,
QWidget *)
{
if (hasFocus()) {
painter->setPen(QPen(QColor(255, 255, 255)));
} else {
painter->setPen(QPen(QColor(100, 100, 100)));
}
painter->setBrush(brushColor);
painter->drawRect(-POS, -POS, WIDTH, HEIGHT);
}
void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
setFocus();
// 设置光标为手握下的形状
setCursor(Qt::ClosedHandCursor);
QGraphicsItem::mousePressEvent(e);
}
void MyItem::keyPressEvent(QKeyEvent *event)
{
if (Qt::Key_Down == event->key())
moveBy(0, 10);
else if(Qt::Key_Up == event->key())
moveBy(0, -10);
else if(Qt::Key_Left == event->key())
moveBy(-10, 0);
else if(Qt::Key_Right == event->key())
moveBy(10, 0);
else{
}
QGraphicsItem::keyPressEvent(event);
}
void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *)
{
// 设置光标为手张开的形状
setCursor(Qt::OpenHandCursor);
setToolTip("click me");
}
void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
QMenu menu;
QAction *moveAction = menu.addAction("move origin");
QAction *selectedAction = menu.exec(event->screenPos());
if (selectedAction == moveAction) {
setPos(0, 0);
}
}
myview.h
myview
继承QGraphicsView,重新实现了滚轮事件,可对场景进行缩放操作
#ifndef MYVIEW_H
#define MYVIEW_H
#include <QObject>
#include <QGraphicsView>
class MyView : public QGraphicsView
{
Q_OBJECT
public:
explicit MyView(QWidget *parent = 0);
protected:
// 滚轮事件:缩放
virtual void wheelEvent(QWheelEvent *event) override;
};
#endif // MYVIEW_H
myview.cpp
#include "myview.h"
#include "myview.h"
#include <QKeyEvent>
MyView::MyView(QWidget *parent) :
QGraphicsView(parent)
{
}
void MyView::wheelEvent(QWheelEvent *event)
{
if(event->delta() > 0)
{
scale(1.1, 1.1);
}else{
scale(0.9, 0.9);
}
// 加上这个,否则在场景和图形项中就没法再接收到该事件了
QGraphicsView::wheelEvent(event);
}
调用
main.cpp
#include <QApplication>
#include "myitem.h"
#include "myview.h"
#include <QTime>
#include <QtMath>
#include <QDebug>
int main(int argc, char* argv[ ])
{
QApplication app(argc, argv);
qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
QGraphicsScene scene;
// 设置场景尺寸,减少动态渲染
scene.setSceneRect(-300, -225, 600, 450);
// 创建项
for (int i = 0; i < 5; ++i) {
MyItem *item = new MyItem;
item->setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
item->setPos(i * 50 - 100, -50);
scene.addItem(item);
}
// 声明视图
MyView view;
view.setScene(&scene);
// 设置背景刷
view.setBackgroundBrush(QBrush(QColor(220, 220, 220)));
view.show();
return app.exec();
}
效果
显示效果如下:文章来源:https://www.toymoban.com/news/detail-759470.html
自定义图形视图文章来源地址https://www.toymoban.com/news/detail-759470.html
到了这里,关于【Qt图形视图框架】自定义QGraphicsItem和QGraphicsView,实现鼠标(移动、缩放)及键盘事件、右键事件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!