Qt Graphics View 绘图架构

发布于:2024-11-27 ⋅ 阅读:(109) ⋅ 点赞:(0)

Qt Graphics View 绘图架构

"QWGraphicsView.h" 头文件代码如下:

#pragma once

#include <QGraphicsView>

class QWGraphicsView : public QGraphicsView
{
	Q_OBJECT

public:
	QWGraphicsView(QWidget *parent);
	~QWGraphicsView();

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

signals:
	void mouseMovePoint(QPoint point);
	void mouseClicked(QPoint point);
};

mouseMoveEvent()是鼠标移动事件,代码如下:

//鼠标移动事件
void QWGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
	QPoint point = event->pos();//QGraphicsView的坐标
	emit mouseMovePoint(point); //释放信号
	QGraphicsView::mouseMoveEvent(event);
}

       在此事件响应代码里,通过事件的pos()函数获取鼠标光标在视图中的坐标point,然后作为参数发射 mouseMovePoint(point)信号。这样,若在其他地方编写槽函数与此信号关联,就可以对鼠标移动事件作出响应。

mousePressEvent()是鼠标按键按下事件,代码如下:

//鼠标左键按下事件
void QWGraphicsView::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		QPoint point = event->pos();//QGraphicsView的坐标
		emit mouseClicked(point);//释放信号
	}
	QGraphicsView::mousePressEvent(event);
}

       在此事件响应代码里,首先判断是否是鼠标左键按下,然后通过事件的pos()函数获取鼠标光标在视图中的坐标point,然后作为参数发射mouseClicked(point)信号。

"sample8_4QGraphicsView.h"  头文件代码如下:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_sample8_4QGraphicsView.h"

#include    <QGraphicsScene>
#include    <QLabel>


class sample8_4QGraphicsView : public QMainWindow
{
	Q_OBJECT

public:
	sample8_4QGraphicsView(QWidget *parent = Q_NULLPTR);

private:
	Ui::sample8_4QGraphicsViewClass ui;

protected:
	void resizeEvent(QResizeEvent *event);

private:
	QGraphicsScene  *scene;

	QLabel  *labViewCord;
	QLabel  *labSceneCord;
	QLabel  *labItemCord;

	void iniGraphicsSystem(); //创建Graphics View的各项

private slots:
	void on_mouseMovePoint(QPoint point);

	void on_mouseClicked(QPoint point);

};

#include "sample8_4QGraphicsView.h"

#include  "ui_sample8_4QGraphicsView.h"
#include   <QGraphicsEllipseItem>


//解决QT中中文显示乱码问题
#pragma execution_character_set("utf-8")


sample8_4QGraphicsView::sample8_4QGraphicsView(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	labViewCord = new QLabel("View 坐标:");
	labViewCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labViewCord);

	labSceneCord = new QLabel("Scene 坐标:");
	labSceneCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labSceneCord);

	labItemCord = new QLabel("Item 坐标:");
	labItemCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labItemCord);

	ui.View->setCursor(Qt::CrossCursor);
	ui.View->setMouseTracking(true);
	ui.View->setDragMode(QGraphicsView::RubberBandDrag);

	QObject::connect(ui.View, SIGNAL(mouseMovePoint(QPoint)),
		this, SLOT(on_mouseMovePoint(QPoint)));

	QObject::connect(ui.View, SIGNAL(mouseClicked(QPoint)),
		this, SLOT(on_mouseClicked(QPoint)));

	iniGraphicsSystem();
}

鼠标移动事件响应:

//鼠标移动事件,point是 GraphicsView的坐标,物理坐标
void sample8_4QGraphicsView::on_mouseMovePoint(QPoint point)
{
	labViewCord->setText(QString::asprintf("View 坐标:%d,%d", point.x(), point.y()));
	QPointF pointScene = ui.View->mapToScene(point); //转换到Scene坐标
	labSceneCord->setText(QString::asprintf("Scene 坐标:%.0f,%.0f", pointScene.x(), pointScene.y()));
}

鼠标单击事件响应:

//鼠标单击事件
void sample8_4QGraphicsView::on_mouseClicked(QPoint point)
{
	QPointF pointScene = ui.View->mapToScene(point); //转换到Scene坐标
	QGraphicsItem  *item = NULL;
	item = scene->itemAt(pointScene, ui.View->transform()); //获取光标下的绘图项
	if (item != NULL) //有绘图项
	{
		QPointF pointItem = item->mapFromScene(pointScene); //转换为绘图项的局部坐标
		labItemCord->setText(QString::asprintf("Item 坐标:%.0f,%.0f", pointItem.x(), pointItem.y()));
	}
}

窗口变化大小时的事件:

//窗口变化大小时的事件
void sample8_4QGraphicsView::resizeEvent(QResizeEvent *event)
{ 
	Q_UNUSED(event);
	//Graphics View坐标,左上角总是(0,0),宽度=,长度=
	ui.labViewSize->setText(QString::asprintf("Graphics View坐标,左上角总是(0,0),宽度=%d,高度=%d",
		ui.View->width(), ui.View->height()));

	QRectF  rectF = ui.View->sceneRect(); //Scene的矩形区
	ui.LabSceneRect->setText(QString::asprintf("QGraphicsView::sceneRect=(Left,Top,Width,Height)=%.0f,%.0f,%.0f,%.0f",
		rectF.left(), rectF.top(), rectF.width(), rectF.height()));
}

构造Graphics View的各项:

//构造Graphics View的各项
void sample8_4QGraphicsView::iniGraphicsSystem()
{
	QRectF   rect(-200, -100, 400, 200);//左上角坐标,宽度,高度
	scene = new QGraphicsScene(rect); //scene逻辑坐标系定义
	ui.View->setScene(scene);


	//画一个矩形框,大小等于scene
	QGraphicsRectItem *item = new QGraphicsRectItem(rect); //矩形框正好等于scene的大小
	item->setFlags(QGraphicsItem::ItemIsSelectable     //可选,可以有焦点,但是不能移动
		| QGraphicsItem::ItemIsFocusable);
	QPen    pen;
	pen.setWidth(2);
	item->setPen(pen);
	//item->setPos(500,0);//缺省位置在scene的(0,0)
	scene->addItem(item);

	//一个位于scene中心的椭圆,测试局部坐标
	QGraphicsEllipseItem *item2 = new QGraphicsEllipseItem(-100, -50, 200, 100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
	item2->setPos(0, 0);//设置椭圆中心位置
	item2->setBrush(QBrush(Qt::blue));
	item2->setFlags(QGraphicsItem::ItemIsMovable //可移动
		| QGraphicsItem::ItemIsSelectable  //可选择
		| QGraphicsItem::ItemIsFocusable); //可获得焦点
	scene->addItem(item2);

	//一个圆,中心位于scene的边缘
	QGraphicsEllipseItem *item3 = new QGraphicsEllipseItem(-50, -50, 100, 100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
	item3->setPos(rect.right(), rect.bottom());//设置圆中心位置
	item3->setBrush(QBrush(Qt::red));
	item3->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
	scene->addItem(item3);

	scene->clearSelection();
	//item->setSelected(true);

	//ui.View->setDragMode(QGraphicsView::RubberBandDrag);
}

运行结果如下:

"QWGraphicsView.cpp" 文件代码如下:

#include "QWGraphicsView.h"

#include    <QMouseEvent>
#include    <QPoint>


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

QWGraphicsView::~QWGraphicsView()
{
}

//鼠标移动事件
void QWGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
	QPoint point = event->pos();//QGraphicsView的坐标
	emit mouseMovePoint(point); //释放信号
	QGraphicsView::mouseMoveEvent(event);
}

//鼠标左键按下事件
void QWGraphicsView::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::LeftButton)
	{
		QPoint point = event->pos();//QGraphicsView的坐标
		emit mouseClicked(point);//释放信号
	}
	QGraphicsView::mousePressEvent(event);
}

"sample8_4QGraphicsView.cpp"  文件代码如下:

#include "sample8_4QGraphicsView.h"

#include  "ui_sample8_4QGraphicsView.h"
#include   <QGraphicsEllipseItem>


//解决QT中中文显示乱码问题
#pragma execution_character_set("utf-8")


sample8_4QGraphicsView::sample8_4QGraphicsView(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	labViewCord = new QLabel("View 坐标:");
	labViewCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labViewCord);

	labSceneCord = new QLabel("Scene 坐标:");
	labSceneCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labSceneCord);

	labItemCord = new QLabel("Item 坐标:");
	labItemCord->setMinimumWidth(150);
	ui.statusBar->addWidget(labItemCord);

	ui.View->setCursor(Qt::CrossCursor);
	ui.View->setMouseTracking(true);
	ui.View->setDragMode(QGraphicsView::RubberBandDrag);

	QObject::connect(ui.View, SIGNAL(mouseMovePoint(QPoint)),
		this, SLOT(on_mouseMovePoint(QPoint)));

	QObject::connect(ui.View, SIGNAL(mouseClicked(QPoint)),
		this, SLOT(on_mouseClicked(QPoint)));

	iniGraphicsSystem();
}

//鼠标移动事件,point是 GraphicsView的坐标,物理坐标
void sample8_4QGraphicsView::on_mouseMovePoint(QPoint point)
{
	labViewCord->setText(QString::asprintf("View 坐标:%d,%d", point.x(), point.y()));
	QPointF pointScene = ui.View->mapToScene(point); //转换到Scene坐标
	labSceneCord->setText(QString::asprintf("Scene 坐标:%.0f,%.0f", pointScene.x(), pointScene.y()));
}

//鼠标单击事件
void sample8_4QGraphicsView::on_mouseClicked(QPoint point)
{
	QPointF pointScene = ui.View->mapToScene(point); //转换到Scene坐标
	QGraphicsItem  *item = NULL;
	item = scene->itemAt(pointScene, ui.View->transform()); //获取光标下的绘图项
	if (item != NULL) //有绘图项
	{
		QPointF pointItem = item->mapFromScene(pointScene); //转换为绘图项的局部坐标
		labItemCord->setText(QString::asprintf("Item 坐标:%.0f,%.0f", pointItem.x(), pointItem.y()));
	}
}

//构造Graphics View的各项
void sample8_4QGraphicsView::iniGraphicsSystem()
{
	QRectF   rect(-200, -100, 400, 200);//左上角坐标,宽度,高度
	scene = new QGraphicsScene(rect); //scene逻辑坐标系定义
	ui.View->setScene(scene);


	//画一个矩形框,大小等于scene
	QGraphicsRectItem *item = new QGraphicsRectItem(rect); //矩形框正好等于scene的大小
	item->setFlags(QGraphicsItem::ItemIsSelectable     //可选,可以有焦点,但是不能移动
		| QGraphicsItem::ItemIsFocusable);
	QPen    pen;
	pen.setWidth(2);
	item->setPen(pen);
	//item->setPos(500,0);//缺省位置在scene的(0,0)
	scene->addItem(item);

	//一个位于scene中心的椭圆,测试局部坐标
	QGraphicsEllipseItem *item2 = new QGraphicsEllipseItem(-100, -50, 200, 100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
	item2->setPos(0, 0);//设置椭圆中心位置
	item2->setBrush(QBrush(Qt::blue));
	item2->setFlags(QGraphicsItem::ItemIsMovable //可移动
		| QGraphicsItem::ItemIsSelectable  //可选择
		| QGraphicsItem::ItemIsFocusable); //可获得焦点
	scene->addItem(item2);

	//一个圆,中心位于scene的边缘
	QGraphicsEllipseItem *item3 = new QGraphicsEllipseItem(-50, -50, 100, 100); //矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
	item3->setPos(rect.right(), rect.bottom());//设置圆中心位置
	item3->setBrush(QBrush(Qt::red));
	item3->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable);
	scene->addItem(item3);

	scene->clearSelection();
	//item->setSelected(true);

	//ui.View->setDragMode(QGraphicsView::RubberBandDrag);
}

//窗口变化大小时的事件
void sample8_4QGraphicsView::resizeEvent(QResizeEvent *event)
{ 
	Q_UNUSED(event);
	//Graphics View坐标,左上角总是(0,0),宽度=,长度=
	ui.labViewSize->setText(QString::asprintf("Graphics View坐标,左上角总是(0,0),宽度=%d,高度=%d",
		ui.View->width(), ui.View->height()));

	QRectF  rectF = ui.View->sceneRect(); //Scene的矩形区
	ui.LabSceneRect->setText(QString::asprintf("QGraphicsView::sceneRect=(Left,Top,Width,Height)=%.0f,%.0f,%.0f,%.0f",
		rectF.left(), rectF.top(), rectF.width(), rectF.height()));
}

"main.cpp"  文件代码如下:

#include "sample8_4QGraphicsView.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	sample8_4QGraphicsView w;
	w.show();
	return a.exec();
}

《Qt5/6 C++开发指南》


网站公告

今日签到

点亮在社区的每一天
去签到