QT学习_QT图形视图

Posted Leslie X徐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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(以上是关于QT学习_QT图形视图的主要内容,如果未能解决你的问题,请参考以下文章

    QT 实用代码片段

    Qt图形视图体系结构

    如何在多个 QT 图形视图小部件之间同步移动

    ✎Qt-doc—QGraphics图形视图框架&坐标系统

    ✎Qt-doc—QGraphics图形视图框架&坐标系统

    ✎Qt-doc—QGraphics图形视图框架&坐标系统