Graphics View绘图构架
- QGraphicsScene(场景):可以管理多个图形项
- QGraphicsItem(图形项):也就是图元,支持鼠标事件响应。
- QGraphicsView(视图):关联场景可以让场景中的所有图形项可视化
QGraphicsView是QT的图形视图组件,在UI设计器的Display Widgets分组
QGraphicsView没有与mouseMoveEvent()相关的信号,需要继承自定义一个派生类
代码演示
工程文件不需要添加模块
注意事项是,graphics需要派生一个类才能用事件等相关信息
所以要新建一个派生类:
mygraphicsview.h
#ifndef MYGRAPHICSVIEW_H
#define MYGRAPHICSVIEW_H
#include <QObject>
#include <QGraphicsView>
class mygraphicsview : public QGraphicsView
{
Q_OBJECT
public:
explicit mygraphicsview(QWidget *parent = nullptr);
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
signals:
void mouseMovePoint(QPoint point);
void mouseClicked(QPoint point);
};
#endif // MYGRAPHICSVIEW_H
mygraphicsview.cpp
#include "mygraphicsview.h"
#include <QMouseEvent>
mygraphicsview::mygraphicsview(QWidget *parent) : QGraphicsView(parent)
{
}
void mygraphicsview::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
QPoint point = event->pos();//view坐标
emit mouseClicked(point);
}
QGraphicsView::mousePressEvent(event);
}
void mygraphicsview::mouseMoveEvent(QMouseEvent *event)
{
QPoint point = event->pos();
emit mouseMovePoint(point);
QGraphicsView::mouseMoveEvent(event);
}
派生类的事件通过信号的方式发送出去,其他地方connect连接信号读取数据。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QLabel>
#include <QMainWindow>
#include <QGraphicsScene>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
QLabel *labViewCord;
QLabel *labSceneCord;
QLabel *labItemCord;
QGraphicsScene *scene;
void initGraphics();
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void on_mouseMovePoint(QPoint point);
void on_mouseClicked(QPoint point);
protected:
void resizeEvent(QResizeEvent *event);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mygraphicsview.h"
#include <QGraphicsRectItem>
void MainWindow::initGraphics()
{
QRectF rect(-200,-100,400,200);
scene = new QGraphicsScene(rect);
ui->graphicsView->setScene(scene);
QGraphicsRectItem *item = new QGraphicsRectItem(rect);
item->setFlags(QGraphicsItem::ItemIsFocusable |
QGraphicsItem::ItemIsSelectable);
QPen pen;
pen.setWidth(2);
item->setPen(pen);
scene->addItem(item);
//蓝色椭圆
QGraphicsEllipseItem *item2 = new QGraphicsEllipseItem(-100,-50,200,100);
item2->setPos(0,0);
item2->setFlags(QGraphicsItem::ItemIsFocusable |
QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemIsMovable);
item2->setBrush(QBrush(Qt::blue));
scene->addItem(item2);
//红色小圆
QGraphicsEllipseItem *item3 = new QGraphicsEllipseItem(-50,-50,100,100);
item3->setPos(rect.right(),rect.bottom());
item3->setFlags(QGraphicsItem::ItemIsFocusable |
QGraphicsItem::ItemIsSelectable |
QGraphicsItem::ItemIsMovable);
item3->setBrush(QBrush(Qt::red));
scene->addItem(item3);
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
labViewCord = new QLabel("View坐标:");
labViewCord->setMidLineWidth(150);
ui->statusbar->addWidget(labViewCord);
labSceneCord = new QLabel("Scene坐标:");
labSceneCord->setMidLineWidth(150);
ui->statusbar->addWidget(labSceneCord);
labItemCord = new QLabel("Item坐标:");
labItemCord->setMidLineWidth(150);
ui->statusbar->addWidget(labItemCord);
ui->graphicsView->setCursor(Qt::CrossCursor);//光标
ui->graphicsView->setMouseTracking(true);//跟随鼠标
connect(ui->graphicsView,&mygraphicsview::mouseMovePoint,
this,&MainWindow::on_mouseMovePoint);
connect(ui->graphicsView,&mygraphicsview::mouseClicked,
this,&MainWindow::on_mouseClicked);
initGraphics();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_mouseMovePoint(QPoint point)
{
labViewCord->setText(QString::asprintf("View坐标:%d,%d",
point.x(),point.y()));
QPointF pointScene = ui->graphicsView->mapToScene(point);
labSceneCord->setText(QString::asprintf("Scene坐标:%.0f,%.0f",
pointScene.x(),pointScene.y()));
}
void MainWindow::on_mouseClicked(QPoint point)
{
QPointF pointScene = ui->graphicsView->mapToScene(point);
QGraphicsItem *item = NULL;
item = scene->itemAt(pointScene,ui->graphicsView->transform());
if(item!=NULL)
{
QPointF pointItem = item->mapFromScene(pointScene);
labItemCord->setText(QString::asprintf("Item坐标%.0f,%.0f",
pointItem.x(),pointItem.y()));
}
}
void MainWindow::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event)
ui->label->setText(QString::asprintf("Graphics View坐标"
"宽=%d,高=%d",
ui->graphicsView->width(),
ui->graphicsView->height()));
QRectF rect = ui->graphicsView->sceneRect();
ui->label_2->setText(QString::asprintf("QGraphicsView::sceneRect="
"(L,T,W,H)=%.0f,%.0f,%.0f,%.0f",
rect.left(),
rect.top(),
rect.width(),
rect.height()));
}
ui部分要注意,需要吧graphics的窗口提升关联到派生类,不要用他的默认类。