热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

py程序的基本结构是哪几个_绘图之GraphicsView程序基本结构和功能实现

点击上方“Qt学视觉”,选择“星标”公众号重磅干货,第一时间送达共同学习共同进步1.实例程序功能实例程序的主要功能包括以下几点•工作区是一个从QGrap

点击上方“Qt学视觉”,选择“星标”公众号重磅干货,第一时间送达

共同学习共同进步

1.实例程序功能

实例程序的主要功能包括以下几点

•工作区是一个从 QGraphicsView继承的自定义类QWGraphicsView,作为绘图的视图组件。 

•创建一个 QGraphicsScene场景,场景的大小就是图中的实线矩形框的大小。 

•改变窗口大小,当视图大于场景时,矩形框总是居于图形视图的中央;当视图小于场景时, 在视图窗口自动出现卷滚条。

•蓝色椭圆正好处于场景的中间,红色圆形位于场景的右下角。当图形项位置不在场景的矩 形框中时,图形项也是可以显示的。

83028ec9c25419e9b5f787e1d1bb6726.png

•当鼠标在窗口上移动时,会在状态栏显示当前光标位置的视图坐标和场景坐标,在某个图 形项上单击鼠标时,还会显示在图形项中的局部坐标。

这个实例演示了 Graphics View绘图几个类的基本使用方法,演示视图、场景和绘图项3个坐 标系的关系,以及它们之间的坐标转换。

2.自定义图形视图组件

    QGraphicsView是Qt的图形视图组件,在UI设计器的Display Widgets分组里可以拖放一个 QGraphicsView组件到窗口上。但是本实例中需要实现鼠标在QGraphicsView上移动时就显示当前 光标的坐标,这涉及mouseMoveEvent()事件的处理。QGraphicsView没有与mouseMoveEvent()相 关的信号,因而无法定义槽函数与此事件相关联。

     为此,从 QGraphicsView 继承定义一个类 QWGraphicsView,实现 mouseMoveEvent()事件和 mousePressEvent()事件,并把鼠标事件转换为信号,这样就可以在主程序里设计槽函数响应这些鼠 标事件。下面是QWGraphicsView类的定义:

class QWGraphicsView : public QGraphicsView 

Q_0BJECT 

protected: 

    void mouseWoveEvent {QMouseEvent *event); 

    void mousePressEvent(QMouseEvent *event); 

public: 

    QWGraphicsView{QWidget *parent = 0); 

signals: 

    void mouseMovePoint(QPoint point); 

    void mouseClicked(QPoint point); 

};

mouseMoveEvent()是鼠标移动事件.其实现代码如下:

void QWGraphicsView::mouseMove£vent(QMouseEvent *event) 

{

    //鼠标移动

    QPoint point=event->pos(); //QGraphicsView 的坐标 

    emit mouseMovePoint (point) ; //发射信岈 

    QGraphicsView::mouseMove£vent(event);

}

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

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

void QWGraphicsView::mousePress£vent(QMouseEvent *event)

    //鼠标左键按下

    if (event->button()==Qt::LeftButton) 

    { 

        QPoint point=event->pos (); //QGraphicsView 的坐标 

        emit mouseClicked (point); 

    } 

    QGraphicsView::mousePressEvent(event); 

}

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

3.主窗口类定义与 QGraphicsView组件升级

    主窗口是一个从QMainWindow继承的类,重定义了resizeEvent()事件,对窗口改变大小的事 件作出响应。槽函数on_mouseMovePoint()响应鼠标在图形视图上移动的事件信号,显示视图坐标 和场景坐标;槽函数 on_ mouseClicked()响应鼠标单击信号,显示图形项的局部坐标:

iniGraphicsSystem()用于创建Graphics View结构的各个对象

MainWindow类的完整定义如下:

class MainWindow : public QMainWindow { Q_OBJECT private: QGraphicsScene *scene; QLabel *labViewCord; QLabel *labSceneCord; QLabel *labItemCord; void iniGraphicsSystem () ; //创建 Graphics View 的各项 protected: void resizeEvent(QResizeEvent *event); public: explicit MainWindow(QWidget *parent = 0); ~MainWindow{); private slots: void on_mouseMovePoint(QPoint point); void on_mouseClicked(QPoint point);private: Ui::MainWindow *ui; };

    主窗口是采用UI设计器进行可视化设计的^在设计界面时,先从组件面板里放一个QGmphicsView 组件到窗口上。但是我们要用的是从QGraphicsView继承的自定义图形视图组件QWGraphicsView, 需要将 QGraphicsView 升级为 QWGraphicsView。

    27f20ef43597f7f2108953fa88b79c3a.png

4 . 窗口初始化 

    下面是主窗口的构造函数的代码:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui (new Ui::MainWindow) { 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->setMinimuraWidth(150); ui->statusBar->addWidget{labltemCord); 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(mousedicked(QPoint)), this, SLOT(on_mouseClicked(QPoint))); iniGraphicsSystem();}

槽函数on_mouseMovePoint()响应鼠标在图形视图上移动的mouseMovePoint()信号,实现代码 如下:

void MainWindow::on_mouseMovePoint(QPoint point) { //鼠标移动事件,point是GraphicsView的坐标,物理坐标 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())); }

    信号传递的参数point就是鼠标在图形视图中的坐标,使用视图组件的mapToScene()函数可 以将此坐标转换为场景中的坐标,这两个坐标在状态栏上显示。

    槽函数on_mouseClicked()响应鼠标在图形视图上单击的mouseClicked()信号,代码如下:

void MainWindow::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())); } }

    信号传递的参数point就是鼠标光标在图形视图中的坐标,先使用视图组件的mapToScene()函数将此坐标转換为场景中的坐标pointScene,然后通过场景对象的itemAt()函数获得光标下的图 形项。如果鼠标光标下有图形项,就用图形项的mapFromScene()函数将pointScene转换为图形项的局部坐标pointItem,并在状态栏上显示。

     另外还定义了窗口的resizeEvent()事件的响应函数,以便在窗口变化大小时,显示视图区域的大小,以及场景的大小信息。其代码如下:

void MainWindow::resize£vent(QResizeEvent *event) { //窗口变化大小时的事件 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)=%.Of,%.Of,%.0f,%.Of",rectF.left(),rectF.top(), rectF.width(), rectF.height())); }

5. Graphics View系统初始化

    构造函数中调用的iniGraphicsSystem()用于创建Graphics View结构中的其他元素,包括场景 和多个图形项。其代码如下:

void MainWindow::iniGraphicsSystem() { //构造Graphics View的各项 QRectF rect(-200,-}00, 400,200> ; //左上角坐标,宽度,高度 scene=new QGraphicsScene (rect) ; "scene 逻辑坐标系定义 ui->View->setScene(scene); //画一个矩形框,大小等于scene QGraphicsRectltem *item=new QGraphicsRectltem(rect); itero->setFlags(QGraphicsItem::ItemlsSelectable //设置 flags |QGraphicsItem::ItemlsFocusable); QPen pen; pen.setWidth(2); item->setPen(pen); scene->addltem(item); //画一个位于scene中心的補圆,测试局部坐标 QGraphicsEllipseltem *item2=new QGraphicsEllipseltem(-100, -50,200,100); item2->setPos(0, 0); item2->setBrush(QBrush(Qt::blue)); item2->setFlags(QGraphicsItem::ItemlsMovable | QGraphicsItem::ItemlsSelectable | QGraphicsItem::ItemlsFocusable); scene->addltem(item2); //画一个圆,中心位于scene的边缘 QGraphicsEllipseltem *item3=new QGraphicsEllipseltem(-50,-50,100,100); item3->setPos(rect.right(),rect.bottom{)); item3->setBrush(QBrush(Qt::red)); item3->setFlags(QGraphicsItem::ItemlsMovable | QGraphicsItem::ItemlsSelectable | QGraphicsItem::ItemlsFocusable); scene->addltem(item3); scene->clearSelection();}

    可视化设计窗体时,将QWGmphicsView类对象的名称命名为View,并且自动填充主窗口的 工作区。创建场景并与View关联的代码如下:

QRectF rect(-200,-100,400,200) ; //左上角坐标,宽度,高度 scene=new QGraphicsScene (rect) ; //scene 逻辑坐标系定义ui->View->setScene(scene);

    这里用一个矩形定义了创建的场景的坐标系统,表示场景的左上角坐标是(-200, -100),场景宽度为400,高度为200,这样,场景的中心点是(0,0),这是场景的坐标系。 

    创建了一个矩形框图形项item,矩形框的大小就等于创建的场景的大小,矩形框不能移动。 

    创建的第二个图形项item2是一个椭圆,椭圆的左上角坐标是(-100,-50),宽度200,高度100, 所以椭圆的中心是(0,0),这是图形项的局部坐标系。再采用setPos(0,0)设置椭圆在场景中的位置, 若不调用setPos()函数设置图形项在场景中的位置,缺省为位置为(0,0)。椭圆设置为可移动、可选择、可以获得焦点。 

    创建的第三个图形项item3是一个圆,圆的左上角坐标是(-50,-50),宽度100,高度100,所以圆的中心是(0,0),这是图形项的局部坐标系。再采用setPos()设置圆在场景中的位置。

item3->setPos(rect.right(),rect.bottom());

其中心位置是场景的右下角,圆的一部分区域是超出了场景的矩形区域的,但是整个圆还是可以正常显示的。从这个实例程序可以看到Graphics View结构中场景与视图的关系,如何创建图形项组件,场景、视图、图形项各自的坐标系以及坐标系之间的转换关系

007eab9c2af09fd098a2715ef7637458.png




推荐阅读
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 开发笔记:实验7的文件读写操作
    本文介绍了使用C++的ofstream和ifstream类进行文件读写操作的方法,包括创建文件、写入文件和读取文件的过程。同时还介绍了如何判断文件是否成功打开和关闭文件的方法。通过本文的学习,读者可以了解如何在C++中进行文件读写操作。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • WPF开发心率检测大数据曲线图的高性能实现方法
    本文介绍了在WPF开发中实现心率检测大数据曲线图的高性能方法。作者尝试过使用Canvas和第三方开源库,但性能和功能都不理想。最终作者选择使用DrawingVisual对象,并结合局部显示的方式实现了自己想要的效果。文章详细介绍了实现思路和具体代码,对于不熟悉DrawingVisual的读者可以去微软官网了解更多细节。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
author-avatar
手机用户2502906263
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有