QT5笔记:36. QGraphicsView 综合示例 (完结撒花!)

通过此示例可以比较熟悉QGraphincsView的流程以及操作

  1. 坐标关系以及获取:

    • View坐标:左上角为原点,通过鼠标移动事件获取
    • Scene坐标:中心为原点,横竖为X,Y轴。通过View.mapToScene(View坐标)获取
    • Item坐标:Item中心为原点,由于可旋转,X,Y轴方向不定。通过item.mapFromScene(Scene坐标,View.Transform)获取
  2. View缩放:X、Y可以不同比例

    ui->graphicsView->scale(1.1, 1.1);//放大
    ui->graphicsView->scale(0.9, 0.9);//缩小
    ui->graphicsView->resetTransform();//恢复比例
    
  3. 设置item可以拖动、选中、获取焦点

     item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsMovable);
    
  4. 可以框选多个

    ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);//鼠标框选
    
  5. item缩放

    item->setScale(item->scale() - 0.1);//缩小
    item->setScale(item->scale() + 0.1);//放大
    item->setScale(1);//恢复比例
    
  6. item旋转

    item->setRotation(item->rotation() - 3);//逆时针转3度
    item->setRotation(item->rotation() + 3);//顺时针转3度
    
  7. item前置&后置

    item->setZValue(item->zValue() + 1);//前置
    item->setZValue(item->zValue() - 1);//后置
    
  8. item组合&打散

    //组合
    QGraphicsItemGroup *group = new QGraphicsItemGroup();
    group->addToGroup(item);
    group->setFlags(QGraphicsItemGroup::ItemIsFocusable | QGraphicsItemGroup::ItemIsSelectable | QGraphicsItemGroup::ItemIsMovable);
    scene->addItem(group);
    
    //打散
    QGraphicsItem *item = scene->selectedItems().at(i);
    if (item->type() == QGraphicsItemGroup::Type) {
        QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(item);
        scene->destroyItemGroup(group);
    }
    
  9. item删除

    scene->removeItem(item);//删除
    

例子:

GraphicsView.h重写的 QGraphicsView,重写鼠标、键盘事件

#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H

#include <QGraphicsView>

class GraphicsView : public QGraphicsView
{
    Q_OBJECT
public:
    explicit GraphicsView(QWidget *parent = nullptr);

signals:
    void keyPress(QKeyEvent *event);
    void mouseDoubleClick(QPoint point);
    void mousePress(QPoint point);
    void mouseMove(QPoint point);

    // QWidget interface
protected:
    void mouseDoubleClickEvent(QMouseEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void keyPressEvent(QKeyEvent *event) override;

};

#endif // GRAPHICSVIEW_H

GraphicsView.cpp

#include "GraphicsView.h"

#include <QMouseEvent>

GraphicsView::GraphicsView(QWidget *parent) : QGraphicsView(parent)
{

}


void GraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        emit(mouseDoubleClick(event->pos()));
    }
    QGraphicsView::mouseDoubleClickEvent(event);//交还事件给父类处理
}

void GraphicsView::mousePressEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        emit(mousePress(event->pos()));
    }
    QGraphicsView::mousePressEvent(event);
}

void GraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    emit(mouseMove(event->pos()));
    QGraphicsView::mouseMoveEvent(event);
}

void GraphicsView::keyPressEvent(QKeyEvent *event)
{
    emit(keyPress(event));
    QGraphicsView::keyPressEvent(event);
}

MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QGraphicsScene>
#include <QLabel>
#include <QMainWindow>
#include <QMouseEvent>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

    QGraphicsScene *scene;
    static const int itemID = 1;
    static const int description = 2;
    int seqNum = 0;//item的ID序列

    QLabel   *labView = new QLabel("View坐标:", this);
    QLabel  *labViewCoord = new QLabel("(000 , 000)\t", this);
    QLabel  *labScene = new QLabel("Scene坐标:", this);
    QLabel  *labSceneCoord = new QLabel("(000 , 000)\t", this);
    QLabel  *labItem = new QLabel("Item坐标:", this);
    QLabel  *labItemCoord = new QLabel("(000 , 000)\t", this);
    QLabel  *labItemID = new QLabel("ItemID:", this);
    QLabel  *labItemInfo = new QLabel("", this);

private slots:
    void onKeyPress(QKeyEvent *event);
    void onMouseDoubleClick(QPoint point);
    void onMousePress(QPoint point);
    void onMouseMove(QPoint point);
    void on_actItem_Rect_triggered();
    void on_actItem_Polygon_triggered();
    void on_actItem_Triangle_triggered();
    void on_actItem_Circle_triggered();
    void on_actItem_Ellipse_triggered();
    void on_actItem_Line_triggered();
    void on_actItem_Text_triggered();
    void on_actZoomIn_triggered();
    void on_actZoomOut_triggered();
    void on_actRestore_triggered();
    void on_actRotateLeft_triggered();
    void on_actRotateRight_triggered();
    void on_actEdit_Front_triggered();
    void on_actEdit_Back_triggered();
    void on_actGroup_triggered();
    void on_actGroupBreak_triggered();
    void on_actEdit_Delete_triggered();
};
#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QColorDialog>
#include <QFontDialog>
#include <QGraphicsRectItem>
#include <QInputDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    scene = new QGraphicsScene(-300, -100, 600, 200);
    ui->graphicsView->setScene(scene);
    ui->graphicsView->setCursor(Qt::CrossCursor);
    ui->graphicsView->setMouseTracking(true);
    ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);//鼠标框选

    ui->statusbar->addWidget(this->labView);
    ui->statusbar->addWidget(this->labViewCoord);
    ui->statusbar->addWidget(this->labScene);
    ui->statusbar->addWidget(this->labSceneCoord);
    ui->statusbar->addWidget(this->labItem);
    ui->statusbar->addWidget(this->labItemCoord);
    ui->statusbar->addWidget(this->labItemID);
    ui->statusbar->addWidget(this->labItemInfo);

    connect(ui->graphicsView, SIGNAL(keyPress(QKeyEvent *)), this, SLOT(onKeyPress(QKeyEvent *)));
    connect(ui->graphicsView, SIGNAL(mouseDoubleClick(QPoint)), this, SLOT(onMouseDoubleClick(QPoint)));
    connect(ui->graphicsView, SIGNAL(mousePress(QPoint)), this, SLOT(onMousePress(QPoint)));
    connect(ui->graphicsView, SIGNAL(mouseMove(QPoint)), this, SLOT(onMouseMove(QPoint)));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actItem_Rect_triggered()//矩形
{
    QBrush brush;
    brush.setColor(QColor(169, 134, 49, 200));
    brush.setStyle(Qt::SolidPattern);

    QGraphicsRectItem *item = new QGraphicsRectItem(-50, -30, 100, 60);
    item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsMovable);
    item->setBrush(brush);
    item->setData(itemID, seqNum++);
    item->setData(description, "矩形");
    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItem_Polygon_triggered()//梯形/多边形
{
    QBrush brush;
    brush.setColor(QColor(255, 78, 55));
    brush.setStyle(Qt::Dense4Pattern);

    QVector<QPointF> points;
    points << QPointF(-50, -70) << QPointF(50, -70) << QPointF(70, -30) << QPointF(-70, -30);
    QPolygonF polygon = QPolygonF(points);
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem(points);
    item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsMovable);
    item->setBrush(brush);
    item->setData(itemID, seqNum++);
    item->setData(description, "梯形");
    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItem_Triangle_triggered()//三角形
{
    QBrush brush;
    brush.setColor(QColor(81, 181, 110));
    brush.setStyle(Qt::Dense4Pattern);

    QVector<QPointF> points;
    points << QPointF(0, -30) << QPointF(-30, 0) << QPointF(30, 0);
    QPolygonF polygon = QPolygonF(points);
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem(points);
    item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsMovable);
    item->setBrush(brush);
    item->setData(itemID, seqNum++);
    item->setData(description, "三角形");
    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItem_Circle_triggered()
{
    QBrush brush;
    brush.setColor(QColor(151, 151, 151));
    brush.setStyle(Qt::SolidPattern);

    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(0, 0, 10, 10);
    item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsMovable);
    item->setBrush(brush);
    item->setData(itemID, seqNum++);
    item->setData(description, "圆形");
    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItem_Ellipse_triggered()
{
    QBrush brush;
    brush.setColor(QColor(195, 195, 195));
    brush.setStyle(Qt::Dense4Pattern);

    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(0, 0, 15, 10);
    item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsMovable);
    item->setBrush(brush);
    item->setData(itemID, seqNum++);
    item->setData(description, "椭圆形");
    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItem_Line_triggered()
{
    QPen pen;
    pen.setWidth(2);

    QGraphicsLineItem *item = new QGraphicsLineItem(-100, 0, 100, 0);
    item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsMovable);
    item->setPen(pen);
    item->setData(itemID, seqNum++);
    item->setData(description, "直线");
    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItem_Text_triggered()
{
    QFont font;
    font.setPointSize(12);
    font.setFamily("MiSans");

    QString text = QInputDialog::getText(this, "", "文本内容");
    QGraphicsTextItem *item = new QGraphicsTextItem(text);
    item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsFocusable | QGraphicsItem::ItemIsMovable);
    item->setFont(font);
    item->setData(itemID, seqNum++);
    item->setData(description, "文本");
    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actZoomIn_triggered()//放大
{
    int count = scene->selectedItems().count();
    if (count != 0) {
        for (int i = 0; i < count; i++) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setScale(item->scale() + 0.1);
        }
    } else {
        ui->graphicsView->scale(1.1, 1.1);
    }
}

void MainWindow::on_actZoomOut_triggered()//缩小
{
    int count = scene->selectedItems().count();
    if (count != 0) {
        for (int i = 0; i < count; i++) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setScale(item->scale() - 0.1);
        }
    } else {
        ui->graphicsView->scale(0.9, 0.9);
    }
}

void MainWindow::on_actRestore_triggered()//恢复比例
{
    int count = scene->selectedItems().count();
    if (count != 0) {
        for (int i = 0; i < count; i++) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setScale(1);
        }
    } else {
        ui->graphicsView->resetTransform();//恢复比例
    }
}

void MainWindow::on_actRotateLeft_triggered()//左旋转
{
    int count = scene->selectedItems().count();
    if (count != 0) {
        for (int i = 0; i < count; i++) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setRotation(item->rotation() - 3);
        }
    }
}

void MainWindow::on_actRotateRight_triggered()//右旋转
{
    int count = scene->selectedItems().count();
    if (count != 0) {
        for (int i = 0; i < count; i++) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setRotation(item->rotation() + 3);
        }
    }
}

void MainWindow::on_actEdit_Front_triggered()//前置
{
    int count = scene->selectedItems().count();
    if (count != 0) {
        for (int i = 0; i < count; i++) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setZValue(item->zValue() + 1);
        }
    }
}

void MainWindow::on_actEdit_Back_triggered()//后置
{
    int count = scene->selectedItems().count();
    if (count != 0) {
        for (int i = 0; i < count; i++) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setZValue(item->zValue() - 1);
        }
    }
}

void MainWindow::on_actGroup_triggered()//组合
{
    int count = scene->selectedItems().count();
    if (count > 0) {
        QGraphicsItemGroup *group = new QGraphicsItemGroup();
        for (int i = count - 1; i >= 0; i--) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setSelected(false);
            group->addToGroup(item);
        }
        group->setFlags(QGraphicsItemGroup::ItemIsFocusable | QGraphicsItemGroup::ItemIsSelectable | QGraphicsItemGroup::ItemIsMovable);
        scene->addItem(group);
        group->setSelected(true);
    }
}

void MainWindow::on_actGroupBreak_triggered()//打散
{
    int count = scene->selectedItems().count();
    if (count > 0) {
        for (int i = count - 1; i >= 0; i--) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            if (item->type() == QGraphicsItemGroup::Type) {
                QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup *>(item);
                scene->destroyItemGroup(group);
            }
        }
    }
}

void MainWindow::on_actEdit_Delete_triggered()//删除
{
    int count = scene->selectedItems().count();
    if (count != 0) {
        for (int i = count - 1; i >= 0; i--) {
            QGraphicsItem *item = scene->selectedItems().at(i);
            scene->removeItem(item);
        }
    }
}

void MainWindow::onMouseDoubleClick(QPoint point)//双击修改颜色或字体
{
    QPointF pointScene = ui->graphicsView->mapToScene(point);
    QGraphicsItem *item = scene->itemAt(pointScene, ui->graphicsView->transform());
    if (item != nullptr) {
        switch (item->type()) {
            case QGraphicsRectItem::Type: {//矩形
                    QGraphicsRectItem *itemRect = qgraphicsitem_cast<QGraphicsRectItem *>(item);
                    QBrush brush = itemRect->brush();
                    QColor color = QColorDialog::getColor(brush.color(), this, "选择一个颜色");
                    if (color.isValid()) {
                        brush.setColor(color);
                        itemRect->setBrush(brush);
                    }
                    break;
                }
            case QGraphicsPolygonItem::Type: {//多边形:梯形、三角形
                    QGraphicsPolygonItem *itemPolygon = qgraphicsitem_cast<QGraphicsPolygonItem *>(item);
                    QBrush brush = itemPolygon->brush();
                    QColor color = QColorDialog::getColor(brush.color(), this, "选择一个颜色");
                    if (color.isValid()) {
                        brush.setColor(color);
                        itemPolygon->setBrush(brush);
                    }
                    break;
                }
            case QGraphicsEllipseItem::Type: {//椭圆 & 圆
                    QGraphicsEllipseItem *itemEllipse = qgraphicsitem_cast<QGraphicsEllipseItem *>(item);
                    QBrush brush = itemEllipse->brush();
                    QColor color = QColorDialog::getColor(brush.color(), this, "选择一个颜色");
                    if (color.isValid()) {
                        brush.setColor(color);
                        itemEllipse->setBrush(brush);
                    }
                    break;
                }
            case QGraphicsTextItem::Type: {//文本
                    QGraphicsTextItem *itemText = qgraphicsitem_cast<QGraphicsTextItem *>(item);
                    bool ok = false;
                    QFont font = QFontDialog::getFont(&ok, itemText->font(), this, "选择字体", QFontDialog::DontUseNativeDialog);
                    if (ok) {
                        itemText->setFont(font);
                    }

                    QColor color = QColorDialog::getColor(itemText->defaultTextColor(), this, "选择一个颜色", QColorDialog::DontUseNativeDialog);//使用Qt的标准颜色对话框而不是操作系统的本机颜色对话框。
                    if (color.isValid()) {
                        itemText->setDefaultTextColor(color);
                    }
                    break;
                }
            case QGraphicsLineItem::Type: {//直线
                    QGraphicsLineItem *itemLine = qgraphicsitem_cast<QGraphicsLineItem *>(item);
                    QPen pen = itemLine->pen();
                    QColor color = QColorDialog::getColor(pen.color(), this, "选择一个颜色");
                    if (color.isValid()) {
                        pen.setColor(color);
                        itemLine->setPen(pen);
                    }
                    break;
                }
            default: break;
        }
    }
}

void MainWindow::onKeyPress(QKeyEvent *event)
{
    QList<QGraphicsItem *> items = scene->selectedItems();
    int count = items.count();
    if (count > 0) {
        switch (event->key()) {
            case Qt::Key_Delete://刪除
            case Qt::Key_Backspace://退格键
                on_actEdit_Delete_triggered();
                break;
            case Qt::Key_Left://左
                for (int i = 0; i < count; i++) {
                    QGraphicsItem *item = items.at(i);
                    item->setX(item->x() - 1);
                }
                break;
            case Qt::Key_Right://右
                for (int i = 0; i < count; i++) {
                    QGraphicsItem *item = items.at(i);
                    item->setX(item->x() + 1);
                }
                break;
            case Qt::Key_Up://上
                for (int i = 0; i < count; i++) {
                    QGraphicsItem *item = items.at(i);
                    item->setY(item->y() - 1);
                }
                break;
            case Qt::Key_Down://下
                for (int i = 0; i < count; i++) {
                    QGraphicsItem *item = items.at(i);
                    item->setY(item->y() + 1);
                }
                break;
            case Qt::Key_Space: on_actRotateRight_triggered(); break;//往右转
            case Qt::Key_PageUp: on_actZoomIn_triggered(); break;//放大
            case Qt::Key_PageDown: on_actZoomOut_triggered(); break;//缩小
        }
    }
}

void MainWindow::onMousePress(QPoint point)//将鼠标点击的itemID显示在状态栏
{
    QPointF pointScene = ui->graphicsView->mapToScene(point);
    QGraphicsItem *item = scene->itemAt(pointScene, ui->graphicsView->transform());
    if (item != nullptr) {
        labItemInfo->setText(item->data(itemID).toString());
    }
}

void MainWindow::onMouseMove(QPoint point)//鼠标移动事件
{
    this->labViewCoord->setText(QString::asprintf("(%4d , %4d)\t", point.x(), point.y()));//View 坐標

    QPointF pointScene  = ui->graphicsView->mapToScene(point);
    this->labSceneCoord->setText(QString::asprintf("(%4.0f , %4.0f)\t", pointScene.x(), pointScene.y()));//Scene 坐標

    QGraphicsItem *item = scene->itemAt(pointScene, ui->graphicsView->transform());
    if (item != nullptr) {
        QPointF itemPoint = item->mapFromScene(pointScene);//item坐标
        this->labItemCoord->setText(QString::asprintf("(%4.0f , %4.0f)\t", itemPoint.x(), itemPoint.x()));
        this->labItemInfo->setText(item->data(itemID).toString());
    } else {
        this->labItemCoord->setText("(0000 , 0000)");
        this->labItemInfo->setText("");
    }
}

界面
image



Qt5 完结撒花,感谢陪伴!!!


reference:

​ 参考视频:https://www.bilibili.com/video/BV1AX4y1w7Nt

NOTICE

  1. 参考视频到此还没有结束,但是我忘记写笔记了,emmmm,大家想看的,可以去B站看
posted @ 2023-03-16 13:50  echo_lovely  阅读(890)  评论(0编辑  收藏  举报