QT学习_QT图形视图

QT图形视图框架Graphics View

一、主要特点

  • 系统可以利用openGL工具改善绘图性能
  • 支持事件传播体系结构
  • 通过二元空间划分树提供快速的图元查找

二、三元素

  1. 场景类(QGraphicsScene):用于放置图元的容器,本身不可见,需要搭配视图类和外界互动.

    • QGraphicsScene::addItem(QGraphicsItem*) : void
    • QGraphicsScene::removeItem(QGraphicsItem*) : void
    • QGraphicsScene::items() : QList<QGraphicsItem*>
    • QGraphicsScene::itemAt(int) : QGraphicsItem*
    • QGraphicsScene::selectedItems() : QList<QGraphicsItem*>
  2. 视图类(QGraphicsView):提供可视窗口,用于显示场景中的图元

    • 场景有关函数
      • QGraphicsView::setScene()
      • QGraphicsView::setSceneRect()
    • 场景和视图坐标转换函数
      • QGraphicsView::mapToScene() : QPointF
      • QGraphicsView::mapFromScene() : QPointF
  3. 图元类(QGraphicsItem)

    • 预置派生类:
      • QGraphicsLineItem
      • QGraphicsEllipseItem
      • QGraphicsTextItem
      • QGraphicsRectItem
      • QGraphicsPolygonItem
      • QGraphicsPathItem
    • 主要绘制函数:
      • QGraphicsItem::setFlags()
      • QGraphicsItem::setBrush()
      • QGraphicsItem::setZValue()
      • QGraphicsItem::setPos()
      • QGraphicsItem::setData()
    • 坐标变换函数:
      • QGraphicsItem::scale()
      • QGraphicsItem::setScale()
      • QGraphicsItem::rotation()
      • QGraphicsItem::setRotation()
      • QGraphicsItem::resetTransform()
    • 主要功能:
      • 处理鼠标按下、移动、释放、双击、悬停、滚轮和右键菜单事件
      • 处理键盘输入事件
      • 处理拖拽事件
      • 分组
      • 碰撞检测
  4. 坐标系

    • 场景类的坐标系原点在其中心点
    • 视图类坐标系原点在其左上角

项目界面

在这里插入图片描述

三、代码分析

  1. 创建场景

    //创建场景
    scene = new QGraphicsScene(-300,-200,600,200);
    ui->View->setScene(scene);
    
  2. 创建并显示图元

    //椭圆
    void MainWindow::on_actItem_Ellipse_triggered()
    {
        QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50,-30,100,60);
        item->setFlags(QGraphicsItem::ItemIsSelectable|
                       QGraphicsItem::ItemIsFocusable|
                       QGraphicsItem::ItemIsMovable);
        item->setBrush(QBrush(Qt::blue));
        item->setZValue(++frontZ);//叠放顺序
        item->setPos((qrand()%100)-50,(qrand()%100)-50);
        item->setData(ItemId,++seqNum); //key,value
        item->setData(ItemDescription,"Ellipse");
    
        scene->addItem(item);
        scene->clearSelection();
        item->setSelected(true);
    }
    
    //矩形
    QGraphicsRectItem *item = new QGraphicsRectItem(-50,-30,100,60);
    
    //圆形
    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50,-50,100,100);
    
    //三角形
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem(QPolygonF(QVector<QPointF>{{0,0},{120,0},{0,-160}}));
    
    //梯形
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem(QPolygonF(QVector<QPointF>{{0,0},{50,-100},{150,-100},{200,0}}));
    
    //文字
    QGraphicsTextItem *item = new QGraphicsTextItem("hello");
    
    
  3. 合并代码

    enum SHAPE{
            RECT,
            ELLIPSE,
            CIRCLE,
            TRIANGLE,
            POLYGON,
            TEXT,
            LINE,
            last
        };
    
    //draw--------------------------------------------------------------------------------
    void MainWindow::on_actItem_Rect_triggered()
    {
        drawItem(SHAPE::RECT);
    }
    
    void MainWindow::on_actItem_Ellipse_triggered()
    {
        drawItem(SHAPE::ELLIPSE);
    }
    
    void MainWindow::on_actItem_Line_triggered()
    {
        drawItem(SHAPE::LINE);
    }
    
    void MainWindow::on_actItem_Circle_triggered()
    {
        drawItem(SHAPE::CIRCLE);
    }
    
    void MainWindow::on_actItem_Triangle_triggered()
    {
        drawItem(SHAPE::TRIANGLE);
    }
    
    void MainWindow::on_actItem_Polygon_triggered()
    {
        drawItem(SHAPE::POLYGON);
    }
    
    void MainWindow::on_actItem_Text_triggered()
    {
        drawItem(SHAPE::TEXT);
    }
    
    void MainWindow::drawItem(int type)
    {
        QGraphicsItem *item=nullptr;
        switch (type) {
        case SHAPE::LINE:
        {
            item = new QGraphicsLineItem(-50,-30,100,60);
            QPen pen(QBrush(Qt::blue),10);
            static_cast<QGraphicsLineItem*>(item)->setPen(pen);
            item->setData(ItemId,SHAPE::LINE);
            item->setData(ItemDescription,"Line");
            break;
        }
        case SHAPE::RECT:
            item = new QGraphicsRectItem(-50,-30,100,60);
            static_cast<QGraphicsRectItem*>(item)->setBrush(QBrush(Qt::blue));
            item->setData(ItemId,SHAPE::RECT);
            item->setData(ItemDescription,"Ractangle");
            break;
        case SHAPE::CIRCLE:
            item = new QGraphicsEllipseItem(-50,-50,100,100);
            static_cast<QGraphicsEllipseItem*>(item)->setBrush(QBrush(Qt::blue));
            item->setData(ItemId,SHAPE::CIRCLE);
            item->setData(ItemDescription,"Circle");
            break;
        case SHAPE::ELLIPSE:
            item = new QGraphicsEllipseItem(-50,-30,100,60);
            static_cast<QGraphicsEllipseItem*>(item)->setBrush(QBrush(Qt::blue));
            item->setData(ItemId,SHAPE::ELLIPSE);
            item->setData(ItemDescription,"Ellipse");
            break;
        case SHAPE::TRIANGLE:
            item = new QGraphicsPolygonItem(QPolygonF(QVector<QPointF>{{0,0},{120,0},{0,-160}}));
            static_cast<QGraphicsPolygonItem*>(item)->setBrush(QBrush(Qt::blue));
            item->setData(ItemId,SHAPE::TRIANGLE);
            item->setData(ItemDescription,"Triangle");
            break;
        case SHAPE::POLYGON:
            item = new QGraphicsPolygonItem(QPolygonF(QVector<QPointF>{{0,0},{50,-100},{150,-100},{200,0}}));
            static_cast<QGraphicsPolygonItem*>(item)->setBrush(QBrush(Qt::blue));
            item->setData(ItemId,SHAPE::POLYGON);
            item->setData(ItemDescription,"Polygon");
            break;
        case SHAPE::TEXT:
            item = new QGraphicsTextItem("hello");
            item->setData(ItemId,SHAPE::TEXT);
            item->setData(ItemDescription,"Text");
            break;
        default:return;
        }
    
        item->setFlags(QGraphicsItem::ItemIsSelectable|
                       QGraphicsItem::ItemIsFocusable|
                       QGraphicsItem::ItemIsMovable);
        item->setZValue(++frontZ);//叠放顺序
        item->setPos((qrand()%100)-50,(qrand()%100)-50);
    
        scene->addItem(item);
        scene->clearSelection();
        item->setSelected(true);
    }
    
    
    
  4. 图元放大缩小

    void MainWindow::on_actZoomIn_triggered()
    {
        int cnt = scene->selectedItems().count();
        if(cnt!=0){
            QGraphicsItem* item;
            for(int i=0;i<cnt;i++){
                item=scene->selectedItems().at(i);
                item->setScale(item->scale()+0.1);
    }}}
    
    void MainWindow::on_actZoomOut_triggered()
    {
        int cnt = scene->selectedItems().count();
        if(cnt!=0){
            QGraphicsItem* item;
            for(int i=0;i<cnt;i++){
                item=scene->selectedItems().at(i);
                item->setScale(item->scale()-0.1);
    }}}
    
  5. 图元左转右转

    void MainWindow::on_actRotateLeft_triggered()
    {
        int cnt = scene->selectedItems().count();
        if(cnt!=0){
            QGraphicsItem* item;
            for(int i=0;i<cnt;i++){
                item=scene->selectedItems().at(i);
                item->setRotation(-30+item->rotation());
    }}}
    
    void MainWindow::on_actRotateRight_triggered()
    {
        int cnt = scene->selectedItems().count();
        if(cnt!=0){
            QGraphicsItem* item;
            for(int i=0;i<cnt;i++){
                item=scene->selectedItems().at(i);
                item->setRotation(30+item->rotation());
    }}}
    
  6. 图元组合和打散

    void MainWindow::on_actGroup_triggered()
    {
        int cnt = scene->selectedItems().count();
        if(cnt>1){
            QGraphicsItemGroup *group = new QGraphicsItemGroup; //create group
            scene->addItem(group); //add to scene
    
            QGraphicsItem* item;
            for(int i=0;i<cnt;i++){
                item=scene->selectedItems().at(0);//注意这里必须为0,加入group后会从scene中删去
                item->setSelected(false);
                item->clearFocus();
                group->addToGroup(item);
            }
    
            group->setFlags(QGraphicsItem::ItemIsSelectable|
                            QGraphicsItem::ItemIsFocusable|
                            QGraphicsItem::ItemIsMovable);
            group->setZValue(++frontZ);
            scene->clearSelection();
            group->setSelected(true);
        }
    }
    
    void MainWindow::on_actGroupBreak_triggered()
    {
        int cnt = scene->selectedItems().count();
        if(cnt>0){
            QGraphicsItemGroup *group;
            for(int i=0;i<cnt;i++){
                group = static_cast<QGraphicsItemGroup*>(scene->selectedItems().at(0));
                scene->destroyItemGroup(group);
            }
        }
    }
    
  7. 按键

    void MainWindow::on_keyPress(QKeyEvent *event)
    {
        if(scene->selectedItems().count()!=1)return; //只能选择一个图形操作
    
        QGraphicsItem *item = scene->selectedItems().at(0);
    
        switch (event->key()) {
        case Qt::Key_Delete:
            scene->removeItem(item);
            break;
        case Qt::Key_Space:
            item->setRotation(90+item->rotation());
            break;
        case Qt::Key_PageUp:
            item->setScale(item->scale()+0.1);
            break;
        case Qt::Key_PageDown:
            item->setScale(item->scale()-0.1);
            break;
        case Qt::Key_Left:
            item->setX(-1+item->x());
            break;
        case Qt::Key_Right:
            item->setX(1+item->x());
            break;
        case Qt::Key_Up:
            item->setY(-1+item->y());
            break;
        case Qt::Key_Down:
            item->setY(1+item->y());
            break;
        }
    }
    
  8. 单击双击事件

    void MainWindow::on_mouseClicked(QPoint point)
    {
        QPointF pointScene = ui->View->mapToScene(point);
        QGraphicsItem *item = NULL;
        item = scene->itemAt(pointScene,ui->View->transform());
        if(item != NULL){
            QPointF pointItem = item->mapFromScene(pointScene);
            labItemCord->setText(QString::asprintf("Item cord:%.0f %.0f",pointItem.x(),pointItem.y()));
            labItemInfo->setText(item->data(ItemDescription).toString());
        }
        else {
            labItemCord->setText(" item cord ");
            labItemInfo->setText(" item info ");
        }
    }
    
    //双击编辑颜色
    template<class T>
    void setBrushColor(T *item)
    {
        QColor color = item->brush().color();
        color = QColorDialog::getColor(color,nullptr,"choose color");
        if(color.isValid()) item->setBrush(QBrush(color));
    }
    
    void MainWindow::on_mouseDoubleClick(QPoint point)
    {
        QPointF pointScene = ui->View->mapToScene(point);
        QGraphicsItem *item = NULL;
        item = scene->itemAt(pointScene,ui->View->transform());
        if(item != NULL){
            switch (item->data(ItemId).toInt()) {
            case SHAPE::RECT:
                setBrushColor<QGraphicsRectItem>(static_cast<QGraphicsRectItem*>(item));
                break;
            case SHAPE::CIRCLE:
                setBrushColor(static_cast<QGraphicsEllipseItem*>(item));
                break;
            case SHAPE::ELLIPSE:
                setBrushColor(static_cast<QGraphicsEllipseItem*>(item));
                break;
            case SHAPE::TRIANGLE:
                setBrushColor(static_cast<QGraphicsPolygonItem*>(item));
                break;
            case SHAPE::POLYGON:
                setBrushColor(static_cast<QGraphicsPolygonItem*>(item));
                break;
            case SHAPE::LINE:
            {
               QGraphicsLineItem* item1 = static_cast<QGraphicsLineItem*>(item);
               QPen pen = item1->pen();
               QColor color = item1->pen().color();
               color = QColorDialog::getColor(color,this,"choose line color");
               if(color.isValid()){
                   pen.setColor(color);
                   item1->setPen(pen);
               }
               break;
            }
            case SHAPE::TEXT:
                {
                    QGraphicsTextItem* item1 = static_cast<QGraphicsTextItem*>(item);
                    QFont font = item1->font();
                    bool ok = false;
                    font = QFontDialog::getFont(&ok,font,this,"set font");
                    if(ok) item1->setFont(font);
                    break;
                }
            }
        }
    }
    
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值