• Qt5开发从入门到精通——第七篇四节( 图形视图—— 图元创建 GraphicsItem V1.1)


    欢迎小伙伴的点评✨✨,相互学习、互关必回、全天在线🍳🍳🍳
    博主🧑🧑 本着开源的精神交流Qt开发的经验、将持续更新续章,为社区贡献博主自身的开源精神👩‍🚀


    前言

    本章节会给大家带来基于图元创建 GraphicsItem V1.0开发升级到图元创建 GraphicsItem V1.1开发的解析。


    一、 GraphicsItem V1.1升级图元闪烁功能解析

    1.1、增添Flashltem类

    • 在 “Graphicsltem” 项目名上单击鼠标右键,在弹出的快捷菜单中选择“添加新文件...“选项,在弹出的对话框中选择 “C++ Class” 选项。单击 “Choose…”按钮,在弹出的对话框的"Base class” 下拉列表框中选择基类名"QObject", 在"Class name" 文本框中输入类的名称"Flashltem" 。
    • Flashltem 类继承自 QGraphicsltem 类和 QObject 类,闪烁效果是通过利用定时器的timerEvent()
      函数定时重画圆的颜色来实现的。
    • 单击“下一步”按钮,单击“完成“按钮,添加文件 “flashitem.h” 和文件 “flashitem.cpp” 。

    1.2、 图元框架中增添闪烁的图元

    (1)在 “mainwindow.h” 文件中添加代码如下:

      public slots:
       void slotAddFlashItem();
      private:
       QAction *addFlashItemAct;
    
    • 1
    • 2
    • 3
    • 4

    (2)在 “mainwindow.cpp” 文件中添加代码如下:

    #include "flashitem.h"
    
    • 1

    其中,在createActionsO函数中添加代码如下:

        addFlashItemAct = new QAction(tr("加入闪烁圆 "),this);
        connect(addFlashItemAct,SIGNAL(triggered()),this,SLOT(slotAddFlashItem()));
    
    
    • 1
    • 2
    • 3

    在 createMenus() 函数中添加代码如下:

    itemsMenu->addAction(addFlashItemAct);
    
    • 1

    在 initScene()函数中添加代码如下:

        for(i=0;i<3;i++)
           slotAddFlashItem() ;
    
    
    • 1
    • 2
    • 3

    函数 slotAddFlashItem()的具体实现代码如下:

    void MainWindow::slotAddFlashItem() //在场景中加入一个闪烁图元
    {
        FlashItem *item= new FlashItem;
        scene->addItem (item);
        item->setPos ((qrand()%int (scene->sceneRect ().width())) -200,
        (qrand()%int (scene->sceneRect().height())) -200);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二、GraphicsItem V1.1 效果实例

    图一
    在这里插入图片描述

    三、原码解析

    flashitem.h

    #ifndef FLASHLTEM_H
    #define FLASHLTEM_H
    #include 
    #include 
    
    class FlashItem : public QObject,public QGraphicsItem
    {
        Q_OBJECT
    public:
        explicit FlashItem(QObject *parent = nullptr);
        QRectF boundingRect() const;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget);
        void timerEvent(QTimerEvent *);
    private:
        bool flash;
        QTimer *timer;
    signals:
    
    public slots:
    };
    
    #endif // FLASHLTEM_H
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include 
    #include 
    #include 
    #include 
    #include 
    
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
        void initScene();         //初始化场景
        void createActions();     //创建主窗体的所有动作
        void createMenus();       //创建主窗体的菜单栏
    public slots:
        void slotNew();           //新建一个显示窗体
        void slotClear ();        //清除场景中所有的图元
        void slotAddEllipseItem();  //在场景中加入一个椭圆形图元
        void slotAddPolygonItem (); //在场景中加入一个多边形图元
        void slotAddTextItem();     //在场景中加入一个文字图元
        void slotAddRectItem ();    //在场景中加入一个长方形图元
        void slotAddAlphaItem();   //在场景中加入一个透明蝴蝶图片
    
        /*定义图元边界的函数 boundingRect(), 完成以图元坐标系为基础,增加两个像素点的冗余工作*/
        void slotAddFlashItem();
    
    
    private:
        QGraphicsScene *scene;
        QAction *newAct;
        QAction *clearAct;
        QAction *exitAct;
        QAction *addEllipseItemAct;
        QAction *addPolygonItemAct;
        QAction *addTextItemAct;
        QAction *addRectItemAct;
        QAction *addAlphaItemAct;
    
        /*********************/
        QAction *addFlashItemAct;
        /*********************/
    
    };
    
    #endif // MAINWINDOW_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    flashitem.cpp

    #include "flashitem.h"
    
    FlashItem::FlashItem(QObject *parent) : QObject(parent)
    {
        flash=true;              //为颜色切换标识赋初值
        setFlag(ItemIsMovable);  //设置图元的属性, ItemIsMovable 表示此图元是可移动的,可 用鼠标进行拖曳操作。
        startTimer(1000);        ///启动一个定时器,以 1000 毫秒为时间间隔
    }
    
    /*定义图元边界的函数 boundingRect(), 完成以图元坐标系为基础,增加两个像素点的冗余工作。*/
    QRectF FlashItem::boundingRect() const
    {
        qreal adjust= 2;
        return QRectF(-10-adjust,-10-adjust,43+adjust,43+adjust);
    }
    
    /*自定义图元重绘的函数 paint()的具体实现代码如下*/
    void FlashItem::paint (QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
    {
        painter->setPen(Qt::NoPen); //闪烁图元的阴影区不绘制边线
        painter->setBrush (Qt:: darkGray); //闪烁图元的阴影区的阴影画刷颜色为深灰
        painter->drawEllipse(-7,-7,40,40); //绘制阴影区
        painter->setPen(QPen(Qt::black,0));
                                              //闪烁区的椭圆边线颜色为黑色、线宽为 0
        /*设置闪烁区的椭圆画刷颜色根据颜色切换标识 flash 决定在椭圆中填充哪种颜色,颜色在红色和黄色之间选择。*/
        painter->setBrush(flash?(Qt::red):(Qt::yellow)); 
        /*绘制与阴影区同样形状和大小的椭圆,并错开一定的距离以实现立体的感觉。*/
        painter->drawEllipse( -10,-10,40,40); //(b)
    }
    
    /*定时器响应函数 timerEvent()完成颜色切换标识的反置,并在每次反置后调用 update()函数
    重绘图元以实现闪烁的效果。*/
    void FlashItem::timerEvent(QTimerEvent *)
    {
        flash=!flash;
        update();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    main.cpp

    #include "mainwindow.h"
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    mainwindow.cpp

    #include "mainwindow.h"
    #include "flashitem.h"
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
    {
         createActions();   //创建主窗体的所有动作
         createMenus();    //创建主窗体的菜单栏
        scene = new QGraphicsScene;
        scene->setSceneRect(-200,-200,400,400);
        initScene (); //初始化场景
        QGraphicsView *view= new QGraphicsView;
        view->setScene(scene);
        view->setMinimumSize(400,400);
        view->show () ;
        setCentralWidget(view);
        resize(550,450);
        setWindowTitle(tr("Graphics Items"));
    }
    
    MainWindow::~MainWindow()
    {
    
    }
    
    void MainWindow::createActions()   //创建主窗体的所有动作
    {
        newAct = new QAction(tr(" 新建 "),this);
        clearAct = new QAction(tr(" 清除") , this) ;
        exitAct = new QAction(tr(" 退出 "),this);
        addEllipseItemAct = new QAction(tr("加入椭圆 "),this);
        addPolygonItemAct = new QAction(tr("加入多边形 "),this);
        addTextItemAct = new QAction(tr("加入文字 "),this);
        addRectItemAct = new QAction(tr("加入长方形 "),this);
        addAlphaItemAct= new QAction(tr("加入透明图片 "),this);
        connect (newAct, SIGNAL (triggered()), this, SLOT (slotNew ()));
        connect(clearAct,SIGNAL (triggered()), this, SLOT (slotClear ()));
        connect (exitAct, SIGNAL (triggered()), this, SLOT (close()));
        connect (addEllipseItemAct,SIGNAL(triggered()), this, SLOT(slotAddEllipseItem ()));
        connect (addPolygonItemAct,SIGNAL(triggered()), this, SLOT(slotAddPolygonItem ())) ;
        connect(addTextItemAct,SIGNAL(triggered()),this,SLOT(slotAddTextItem ())) ;
        connect(addRectItemAct,SIGNAL(triggered()),this,SLOT(slotAddRectItem ()));
        connect(addAlphaItemAct,SIGNAL(triggered()),this,SLOT(slotAddAlphaItem()));
    
        /*******************************************/
        addFlashItemAct = new QAction(tr("加入闪烁圆 "),this);
        connect(addFlashItemAct,SIGNAL(triggered()),this,SLOT(slotAddFlashItem()));
    }
    
    
    void MainWindow::createMenus()    //创建主窗体的菜单栏
    {
    
        QMenu *fileMenu = menuBar () ->addMenu (tr(" 文件")) ;
        fileMenu->addAction(newAct);
        fileMenu->addAction(clearAct);
        fileMenu->addSeparator();
        fileMenu->addAction(exitAct);
        QMenu *itemsMenu = menuBar()->addMenu(tr(" 元素")) ;
        itemsMenu->addAction(addEllipseItemAct);
        itemsMenu->addAction(addPolygonItemAct);
        itemsMenu->addAction(addTextItemAct);
        itemsMenu->addAction(addRectItemAct);
        itemsMenu->addAction(addAlphaItemAct);
    
        /**********************************/
        itemsMenu->addAction(addFlashItemAct);
    }
    
    
    void MainWindow:: initScene ()     //初始化场景
    {
        int i;
        for(i=0;i<3;i++)
          slotAddEllipseItem ();
        for(i=0;i<3;i++)
          slotAddPolygonItem();
        for(i=0;i<3;i++)
          slotAddTextItem () ;
        for(i=0;i<3;i++)
          slotAddRectItem();
        for(i=0;i<3;i++)
          slotAddAlphaItem();
        for(i=0;i<3;i++)
           slotAddFlashItem() ;
    }
    
    
    void MainWindow::slotNew()   //新建一个显示窗体
    {
        slotClear();
        initScene();
        MainWindow *newWin = new MainWindow;
        newWin->show ();
    }
    
    void MainWindow::slotClear()  //清除场景中所有的图元
    {
        QList<QGraphicsItem*>listItem = scene->items();
        while (!listItem.empty())
        {
            scene->removeItem(listItem.at (0));
            listItem.removeAt(0);
        }
    
    
    }
    
    void MainWindow::slotAddEllipseItem()  //在场景中加入一个椭圆形图元
    {
        QGraphicsEllipseItem *item= new QGraphicsEllipseItem(QRectF(0,0,80,60));
        item->setPen (Qt::NoPen);
        item->setBrush(QColor(qrand() %256,qrand() %256,qrand() %256));
        item->setFlag(QGraphicsItem::ItemIsMovable);
        scene->addItem(item);
        item->setPos((qrand() %int (scene->sceneRect () . width())) -200,
        (qrand () %int (scene->sceneRect () . height ())) -200);
    }
    
    
    void MainWindow::slotAddPolygonItem()  //在场景中加入一个多边形图元
    {
        QVector<QPoint> v;
        v<<QPoint(30,-15)<<QPoint(0,-30)<<QPoint(-30,-15)
        <<QPoint(-30,15)<<QPoint(0,30)<<QPoint(30,15);
        QGraphicsPolygonItem *item= new QGraphicsPolygonItem(QPolygonF(v));
        item->setBrush (QColor(qrand()%256, qrand () %256, qrand ()%256));
        item->setFlag(QGraphicsItem::ItemIsMovable);
        scene->addItem(item);
        item->setPos((qrand()%int (scene->sceneRect ().width()))-200,
        (qrand() %int (scene->sceneRect().height())) -200);
    
    }
    
    void MainWindow::slotAddTextItem()  //在场景中加入一个文字图元
    {
        QFont font("Times",16);
        QGraphicsTextItem *item= new QGraphicsTextItem("Hello Qt");
        item->setFont(font);
        item->setFlag(QGraphicsItem::ItemIsMovable);
        item->setDefaultTextColor(QColor(qrand()%256, qrand()%256, qrand ()%256));
        scene->addItem(item);
        item->setPos((qrand()%int (scene->sceneRect().width())) -200,
        (qrand()%int(scene->sceneRect() .height ()))-200);
    }
    
    
    void MainWindow::slotAddRectItem() //在场景中加入一个长方形图元
    {
        QGraphicsRectItem *item= new QGraphicsRectItem(QRectF(0,0, 60,60));
        QPen pen;
        pen.setWidth(3);
        pen. setColor(QColor(qrand()%256, qrand ()%256, qrand()%256));
        item->setPen(pen);
        item->setBrush (QColor (qrand()%256, qrand()%256, qrand()%256));
        item->setFlag(QGraphicsItem::ItemIsMovable);
        scene->addItem(item);
        item->setPos ((qrand()%int (scene->sceneRect ().width())) -200,
        (qrand()%int (scene->sceneRect ().height())) -200);
    }
    
    void MainWindow::slotAddAlphaItem()  ///在场景中加入一个皮卡丘图片
    {
        QGraphicsPixmapItem *item=scene->addPixmap(QPixmap(":/src/piKa.png"));
        item->setFlag(QGraphicsItem::ItemIsMovable);
        item->setPos ((qrand ()%int (scene->sceneRect ().width())) -200,
        (qrand() %int (scene->sceneRect().height())) -200) ;
    }
    
    
    void MainWindow::slotAddFlashItem() //在场景中加入一个闪烁图元
    {
        FlashItem *item= new FlashItem;
        scene->addItem (item);
        item->setPos ((qrand()%int (scene->sceneRect ().width())) -200,
        (qrand()%int (scene->sceneRect().height())) -200);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177

    四、总结

    图元创建会在应用程序开发中经常用到的

  • 相关阅读:
    Nginx配置SSL证书
    锐捷网络有限公司自工序完结项目圆满结束
    Windows和Linux的环境变量
    9.18 QT作业
    boundary IoU 的计算方式
    2022高教社杯辅导 答疑 选题 代码 思路 全国大学生数学建模竞赛
    路由器桥接设置(扩大wifi信号)
    2.物联网射频识别,RFID通信原理,RFID读写器与标签无线交互方式、数据反馈方式,RFID调制与解调、编码方式,不同RFID标签与读写器
    数据存储——声音存储
    2、项目第三阶段——代码优化
  • 原文地址:https://blog.csdn.net/weixin_44759598/article/details/126924450