八、Qt绘图

一、QPainter基本绘制

Qt可以使用相同的API在屏幕和绘图设备上进行绘制,它主要基于QPainter、QPaintDevice和QPaintEngine这个三个类。
  • QPainter:用来进行绘图操作。QPainter一般在部件的绘制事件paintEvent()中进行绘制,当窗口程序需要升级或者重新绘制时,调用此函数。使用repaint()和update()后,调用函数painEvent().
  • QPaintDevice:抽象的二维界面,是中间媒介。QPainter可以在继承自QPaintDevice类的任何对象上进行绘制操作。
  • QPaintEngine:提供了一些接口,可用于QPainter在不同的设备上进行绘制

1、Painter主要功能

QPainter三个主要设置:pen,brush,font
painter.setPen(QPen(...));
painter.setBrush(QBrush(...));	// 填充效果
painter.setFont(QFont(...));
painter.setRenderHint(QPainter::Antialiasing);  // 抗锯齿
painter.drawXXX(...);

2、实现工具

(1)创建项目,基于QWidget

(2)添加图标资源

(3)绘制基本图形

void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter(this);
    int w = this->width();
    int h = this->height();
    //    painter.setRenderHint(QPainter::Antialiasing);
    //    painter.setRenderHint(QPainter::TextAntialiasing);
    QPen pen;
    pen.setWidth(20);
    pen.setColor(Qt::red);
    pen.setStyle(Qt::DashDotDotLine); // 点线
    pen.setJoinStyle(Qt::RoundJoin); // 圆角
    painter.setPen(pen);

    QBrush brush;
    brush.setColor(Qt::blue);
    brush.setStyle(Qt::Dense5Pattern); // 填充样式
    painter.setBrush(brush);

    QRect rect(w / 4, h / 4, w / 2, h / 2);
    painter.drawRect(rect);
}

八、Qt绘图_第1张图片

(4)绘制图片与文字

    QRect rect(w / 4, h / 4, w / 2, h / 2);
    painter.drawRect(rect);

    QImage image(":/images/images/favicon.png");
    painter.drawImage(rect, image);

    QFont font;
    font.setPointSize(20);
    painter.setFont(font);
    painter.drawText(rect, "Test");

八、Qt绘图_第2张图片

(5)画线

QPoint points[] = {QPoint(w / 3, h / 3), QPoint(w / 2, h / 2), QPoint(w / 2, 2 * h / 3)};
    painter.drawPolyline(points, 3);

八、Qt绘图_第3张图片

二、坐标体统和坐标转换

QPainter提供了一些坐标变换,通过平移、旋转、缩放等坐标变换得到一个逻辑坐标系统,使用逻辑坐标系统可以更方便绘图。
  • 坐标变换
    • void translate(qreal dx, qreal dy) 坐标系统偏移,坐标原点偏移到新位置
    • void roate(qreal angle) 坐标系统顺时针旋转
    • void scale(qreal sx, qreal sy) 坐标体统缩放
    • void shear(qreal sh, qreal sy) 坐标系统左扭转变换
  • 状态保存与恢复
    • void save() 保存painter当前的状态,即将当前的状态压入栈
    • void restore() 恢复上一次状态,即从对战中弹出上一次的状态
    • void restTransform() 复位所有的坐标变换

1、实现程序

(1)创建项目,基于QWidget

(2)绘制图形

#include "widget.h"
#include "ui_widget.h"

#include 
#include 

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

    setPalette(QPalette(Qt::white));
    setAutoFillBackground(true);
    resize(600, 300);
}

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


void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter(this);
    QPen pen;
    pen.setStyle(Qt::SolidLine);
    painter.setPen(pen);
    painter.setRenderHint(QPainter::Antialiasing);

    QBrush brush;
    brush.setColor(Qt::blue);
    brush.setStyle(Qt::SolidPattern);
    painter.setBrush(brush);

    qreal R = 100;
    qreal deg = 3.14159 * (360 / 5) / 180;
    QPoint points[5] =
    {
        QPoint(R, 0),
        QPoint(R * std::cos(deg), -R * std::sin(deg)),
        QPoint(R * std::cos(2 * deg), -R * std::sin(2 * deg)),
        QPoint(R * std::cos(3 * deg), -R * std::sin(3 * deg)),
        QPoint(R * std::cos(4 * deg), -R * std::sin(4 * deg))
    };

    QPainterPath painterPath;
    painterPath.moveTo(points[3]);
    painterPath.lineTo(points[1]);
    painterPath.lineTo(points[4]);
    painterPath.lineTo(points[2]);
    painterPath.lineTo(points[0]);
    painterPath.closeSubpath();

    QFont font;
    font.setPointSize(15);
    painterPath.addText(points[0], font, "0");
    painterPath.addText(points[1], font, "1");
    painterPath.addText(points[2], font, "2");
    painterPath.addText(points[3], font, "3");
    painterPath.addText(points[4], font, "4");

    painter.setFont(font);

    painter.save();
    painter.translate(100, 120);    // 起始坐标
    painter.drawPath(painterPath);
    painter.drawText(0, 0, "S1");

    painter.restore();
    painter.translate(300, 120);
    painter.rotate(90); // 旋转90度
    painter.scale(0.5, 0.5); //缩放
    painter.drawPath(painterPath);
    painter.drawText(0, 0, "S2");

    painter.resetTransform();
    painter.translate(500, 150);
    painter.rotate(-90); // 旋转-90度
    painter.scale(1.5, 0.5); //缩放
    painter.drawPath(painterPath);
    painter.drawText(0, 0, "S3");
}

八、Qt绘图_第4张图片

三、视口和窗口

  • 视口(实际大小):绘图设备的任意一个矩形区域的物理坐标,可以只选取物理坐标的一个矩形区域用于绘图。视口默认情况下等于绘图设备的整个矩形区。
  • 窗口(相对大小):对于视口的矩形区域,只不过是用逻辑坐标定义的坐标系,窗口坐标的中心在矩阵中心。

1、实现程序

(1)创建项目,基于QWidget

(2)绘图

#include "widget.h"
#include "ui_widget.h"

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

    setPalette(QPalette(Qt::white));
    setAutoFillBackground(true);
    resize(300, 300);
}

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

void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)

    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    int w = width();
    int h = height();

    painter.drawEllipse(QPoint(0, 0), 50, 50);

    int side = qMin(h, w);
    QRect rect((w - side) / 2, (h - side) / 2, side, side); // 选取中心最大矩形
    painter.drawRect(rect);
    painter.setViewport(rect);  // 设置区域
    painter.setWindow(-100, -100, 200, 200); //设置相对坐标系

    QLinearGradient linearGradient(0, 0, 100, 0); //0,0到100,0 颜色渐变
    linearGradient.setColorAt(0, Qt::blue);
    linearGradient.setColorAt(1, Qt::red);
    linearGradient.setSpread(QGradient::PadSpread); // 边界发散
    painter.setCompositionMode(QPainter::RasterOp_NotSourceXorDestination); //设置混合模式
    painter.setBrush(linearGradient);

    for (int i = 0; i < 36; ++i)
    {
        painter.drawEllipse(QPoint(50, 0), 50, 50);
        painter.rotate(10);
    }
}

八、Qt绘图_第5张图片

四、Graphics View场景、视图与图形项

1、Graphics View绘图架构

QPainter不能实现图件选择、编辑、拖拽、修改等功能
  • QGrapicsView(视图):关联场景可以让场景中的所有图形项可视化
  • QGraphicsScene(场景):可以管理多个图形项
  • QGrapicsItem(图形项):是图元,支持鼠标事件响应,比如矩形的图形项
    八、Qt绘图_第6张图片
    QGraphicsView是Qt的图形视图组件,在UI设计器的Display Widgets分组中。QGraphicsView没有与mouseMoveEvent()相关的信号,需要继承自定义一个派生类。
场景图形项类的继承关系
QGraphicsItem
	QAbstractGraphicsShapeItem
		QGraphicsEclipseItem
		QGraphicsPathItem
		QGraphicsPlogonItem
		QGraphicsRectItem
		QGraphicsSimpleTextItem	
	QGraphicsLineItem
	QGraphicsPixmapItem
	QGraphicsObject
		QGraphicstextItem
	QGraphicsItemGroup

2、实现程序

(1)创建项目,基于QMainWindow

(2)添加组件

八、Qt绘图_第7张图片

(3)添加类

八、Qt绘图_第8张图片

(4)提升类

提升原因:QGraphicsView没有鼠标移动事件,需要使用新的继承类实现鼠标事件。

八、Qt绘图_第9张图片
八、Qt绘图_第10张图片
八、Qt绘图_第11张图片

(5)实现鼠标事件监听

protected:
    // 重写鼠标事件槽函数
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;

signals:
    // 鼠标事件信号
    void mouseMovePoint(QPoint point);
    void mouseClicked(QPoint point);

(6)实现功能

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

#include 

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

    labViewCord = new QLabel("View坐标:");
    labViewCord->setMinimumWidth(200);
    ui->statusBar->addWidget(labViewCord);
    labSceneCord = new QLabel("Scene坐标:");
    labSceneCord->setMinimumWidth(200);
    ui->statusBar->addWidget(labSceneCord);
    labItemCord = new QLabel("Item坐标:");
    labItemCord->setMinimumWidth(200);
    ui->statusBar->addWidget(labItemCord);

    ui->graphicsView->setCursor(Qt::CrossCursor); // 光标
    ui->graphicsView->setMouseTracking(true); // 支持鼠标跟踪

    connect(ui->graphicsView, SIGNAL(mouseMovePoint(QPoint)),
            this, SLOT(on_mouseMovePoint(QPoint)));
    connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)),
            this, SLOT(on_mouseClicked(QPoint)));

}

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

void MainWindow::initGraphics()
{
    QRectF rect(-200, -100, 400, 200);
    scene = new QGraphicsScene(rect);
    ui->graphicsView->setScene(scene);

    QGraphicsRectItem *item = new QGraphicsRectItem(rect);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable); //可选中

    QPen pen;
    pen.setWidth(5);
    item->setPen(pen);
    scene->addItem(item);

    QGraphicsEllipseItem *item2 = new QGraphicsEllipseItem(-100, -50, 200, 100);
    item2->setBrush(QBrush(Qt::blue));
    item2->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                    QGraphicsItem::ItemIsSelectable | //可选中
                    QGraphicsItem::ItemIsMovable); // 可移动
    scene->addItem(item2);

    QGraphicsEllipseItem *item3 = new QGraphicsEllipseItem(-50, -50, 100, 100);
    item3->setPos(rect.right(), rect.bottom()); //将item3的原点坐标移至矩形右下角
    item3->setBrush(QBrush(Qt::red));
    item3->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                    QGraphicsItem::ItemIsSelectable | //可选中
                    QGraphicsItem::ItemIsMovable); // 可移动
    scene->addItem(item3);
}

void MainWindow::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event)
    ui->labelViewSize->setText(QString::asprintf("Graphics View坐标,宽=%d,高=%d",
                               ui->graphicsView->width(),
                               ui->graphicsView->height()));
    QRectF rect = ui->graphicsView->sceneRect();
    ui->labelSceneRect->setText(QString::asprintf("QGraphicsView::sceneRect=(%.3f,%.3f,%.3f,%.3f)",
                                rect.left(), rect.top(), rect.width(), rect.height()));
}

void MainWindow::on_mouseMovePoint(QPoint point)
{
    labViewCord->setText(QString::asprintf("View坐标:%d,%d", point.x(), point.y()));
    QPointF pointScene = ui->graphicsView->mapToScene(point);
    labSceneCord->setText(QString::asprintf("Scene坐标:%.3f,%.3f", pointScene.x(), pointScene.y()));


}

void MainWindow::on_mouseClicked(QPoint point)
{
    QPointF pointScene = ui->graphicsView->mapToScene(point);
    QGraphicsItem *item = nullptr;
    item = scene->itemAt(pointScene, ui->graphicsView->transform()); // 根据坐标选择item

    if(item != nullptr)
    {
        QPointF pointItem = item->mapFromScene(pointScene);
        labItemCord->setText(QString::asprintf("Item坐标:%.3f,%.3f", pointItem.x(), pointItem.y()));
    }
}

八、Qt绘图_第12张图片

五、Graphics View绘图

1、框架

(1)创建项目,基于QMainWindow

(2)添加图标资源,创建工具栏图标

八、Qt绘图_第13张图片

(3)添加类,为Graphics View组件提升类

(4)添加信号与槽函数

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

private:
    void keyPressEvent(QKeyEvent *event) override;
    void mouseDoubleClickEvent(QMouseEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    //    void mouseMoveEvent(QMouseEvent *event) override;

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

public slots:
};
#include "mygraphicsview.h"
#include 

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

}

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

void MyGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)
    {
        QPoint point = event->pos();
        emit mouseDoubleClick(point);
    }

    QGraphicsView::mouseDoubleClickEvent(event);
}

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

    QGraphicsView::mousePressEvent(event);
}

2、绘图

void MainWindow::on_actItemRect_triggered()
{
    QGraphicsRectItem *item = new QGraphicsRectItem(-50, -30, 100, 60);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::yellow));
    item->setPos(-100 + qrand() % 200, -60 + qrand() % 120);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "矩形");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItemCircle_triggered()
{
    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50, -50, 100, 100);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::red));
    item->setPos(-100 + qrand() % 200, -100 + qrand() % 200);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "圆形");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItemElliptic_triggered()
{
    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50, -30, 100, 60);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::blue));
    item->setPos(-100 + qrand() % 200, -60 + qrand() % 130);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "椭圆");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItemLine_triggered()
{
    QGraphicsLineItem *item = new QGraphicsLineItem(-100, 0, 100, 0);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    QPen pen;
    pen.setColor(Qt::black);
    pen.setWidth(5);

    item->setPen(pen);
    item->setPos(-100 + qrand() % 200, -60 + qrand() % 130);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "直线");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

#include 
void MainWindow::on_actItemTrapezoid_triggered()
{
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem;

    QPolygonF polygon;
    polygon.append(QPointF(-40, -40));
    polygon.append(QPointF(40, -40));
    polygon.append(QPointF(60, 40));
    polygon.append(QPointF(-60, 40));
    item->setPolygon(polygon);

    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::green));
    item->setPos(-100 + qrand() % 200, -100 + qrand() % 200);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "梯形");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItemTriangle_triggered()
{
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem;

    QPolygonF polygon;
    polygon.append(QPointF(0, -40));
    polygon.append(QPointF(-60, 40));
    polygon.append(QPointF(60, 40));
    item->setPolygon(polygon);

    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::darkGray));
    item->setPos(-100 + qrand() % 200, -100 + qrand() % 200);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "三角形");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

#include 
void MainWindow::on_actItemText_triggered()
{
    QString str = QInputDialog::getText(this, "输入对话框", "请输入:");

    QGraphicsTextItem *item = new QGraphicsTextItem(str);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    QFont font;
    font.setPointSize(20);

    item->setFont(font);
    item->setDefaultTextColor(Qt::darkBlue);
    item->setPos(-100 + qrand() % 200, -60 + qrand() % 130);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "文字");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

3、控制

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

#include 
#include 


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

    setCentralWidget(ui->graphicsView);
    labelItemInfo = new QLabel("ItemInfo");
    labelItemInfo->setMinimumWidth(150);
    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(labelItemInfo);

    connect(ui->graphicsView, SIGNAL(keyPress(QKeyEvent*)),
            this, SLOT(on_keyPress(QKeyEvent*)));
    connect(ui->graphicsView, SIGNAL(mouseDoubleClick(QPoint)),
            this, SLOT(on_mouseDoubleClick(QPoint)));
    connect(ui->graphicsView, SIGNAL(mousePress(QPoint)),
            this, SLOT(on_mousePress(QPoint)));

}

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

#include 
void MainWindow::on_keyPress(QKeyEvent *event)
{
    int cnt = scene->selectedItems().count();

    if(cnt == 0)
    {
        return;
    }

    switch (event->key())
    {
    case Qt::Key_Delete:
    {
        for (int i = 0; i < cnt; ++i)
        {
            QGraphicsItem *item = scene->selectedItems().at(0);
            scene->removeItem(item);
        }
    }
    break;

    case Qt::Key_Left:
    {
        for (int i = 0; i < cnt; ++i)
        {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setX(item->x() - 1);
        }
    }
    break;

    case Qt::Key_Right:
    {
        for (int i = 0; i < cnt; ++i)
        {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setX(item->x() + 1);
        }
    }
    break;

    case Qt::Key_Up:
    {
        for (int i = 0; i < cnt; ++i)
        {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setY(item->y() - 1);
        }
    }
    break;

    case Qt::Key_Down:
    {
        for (int i = 0; i < cnt; ++i)
        {
            QGraphicsItem *item = scene->selectedItems().at(i);
            item->setY(item->y() + 1);
        }
    }
    break;
    }
}

#include 

void MainWindow::on_mouseDoubleClick(QPoint point)
{
    QPointF pointScene = ui->graphicsView->mapToScene(point);
    QGraphicsItem *item = nullptr;
    item = scene->itemAt(pointScene, ui->graphicsView->transform()); //当前的交换矩阵

    if(item == nullptr)
    {
        return;
    }

    switch (item->type())
    {
    case QGraphicsRectItem::Type:
    {
        QGraphicsRectItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
        QColor color = theItem->brush().color();
        color = QColorDialog::getColor(color, nullptr, "选择颜色");

        if(color.isValid())
        {
            theItem->setBrush(QBrush(color));
        }
    }
    break;

    case QGraphicsEllipseItem::Type:
    {
        QGraphicsEllipseItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
        QColor color = theItem->brush().color();
        color = QColorDialog::getColor(color, nullptr, "选择颜色");
        theItem->setBrush(QBrush(color));
    }
    break;

    case QGraphicsPolygonItem::Type:
    {
        QGraphicsPolygonItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
        QColor color = theItem->brush().color();
        color = QColorDialog::getColor(color, nullptr, "选择颜色");
        theItem->setBrush(QBrush(color));
    }
    break;

    case QGraphicsLineItem::Type:
    {
        QGraphicsLineItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
        QColor color = theItem->pen().color();
        color = QColorDialog::getColor(color, nullptr, "选择颜色");
        theItem->setPen(QPen(color));
    }
    break;

    case QGraphicsTextItem::Type:
    {
        QGraphicsTextItem *theItem;
        theItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
        QColor color = theItem->defaultTextColor();
        color = QColorDialog::getColor(color, nullptr, "选择颜色");
        theItem->setDefaultTextColor(color);
    }
    break;
    }
}

void MainWindow::on_mousePress(QPoint point)
{
    QPointF pointScene = ui->graphicsView->mapToScene(point);
    QGraphicsItem *item = nullptr;
    item = scene->itemAt(pointScene, ui->graphicsView->transform()); //当前的交换矩阵

    if(item != nullptr)
    {
        labelItemInfo->setText("ItemInfo: " + item->data(ItemID).toString() +
                               "," + item->data(ItemDescription).toString());
    }

}

void MainWindow::on_actItemRect_triggered()
{
    QGraphicsRectItem *item = new QGraphicsRectItem(-50, -30, 100, 60);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::yellow));
    item->setPos(-100 + qrand() % 200, -60 + qrand() % 120);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "矩形");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItemCircle_triggered()
{
    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50, -50, 100, 100);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::red));
    item->setPos(-100 + qrand() % 200, -100 + qrand() % 200);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "圆形");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItemElliptic_triggered()
{
    QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50, -30, 100, 60);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::blue));
    item->setPos(-100 + qrand() % 200, -60 + qrand() % 130);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "椭圆");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItemLine_triggered()
{
    QGraphicsLineItem *item = new QGraphicsLineItem(-100, 0, 100, 0);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    QPen pen;
    pen.setColor(Qt::black);
    pen.setWidth(5);

    item->setPen(pen);
    item->setPos(-100 + qrand() % 200, -60 + qrand() % 130);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "直线");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

#include 
void MainWindow::on_actItemTrapezoid_triggered()
{
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem;

    QPolygonF polygon;
    polygon.append(QPointF(-40, -40));
    polygon.append(QPointF(40, -40));
    polygon.append(QPointF(60, 40));
    polygon.append(QPointF(-60, 40));
    item->setPolygon(polygon);

    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::green));
    item->setPos(-100 + qrand() % 200, -100 + qrand() % 200);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "梯形");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actItemTriangle_triggered()
{
    QGraphicsPolygonItem *item = new QGraphicsPolygonItem;

    QPolygonF polygon;
    polygon.append(QPointF(0, -40));
    polygon.append(QPointF(-60, 40));
    polygon.append(QPointF(60, 40));
    item->setPolygon(polygon);

    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    item->setBrush(QBrush(Qt::darkGray));
    item->setPos(-100 + qrand() % 200, -100 + qrand() % 200);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "三角形");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

#include 
void MainWindow::on_actItemText_triggered()
{
    QString str = QInputDialog::getText(this, "输入对话框", "请输入:");

    QGraphicsTextItem *item = new QGraphicsTextItem(str);
    item->setFlags(QGraphicsItem::ItemIsFocusable | // 聚焦
                   QGraphicsItem::ItemIsSelectable | // 选择
                   QGraphicsItem::ItemIsMovable );// 移动

    QFont font;
    font.setPointSize(20);

    item->setFont(font);
    item->setDefaultTextColor(Qt::darkBlue);
    item->setPos(-100 + qrand() % 200, -60 + qrand() % 130);
    item->setData(ItemID, ++seqNum);
    item->setData(ItemDescription, "文字");


    scene->addItem(item);
    scene->clearSelection();
    item->setSelected(true);
}

void MainWindow::on_actZoomIn_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt <= 0)
    {
        ui->graphicsView->scale(1.1, 1.1);
        return;
    }

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(i);
        item->setScale(0.1 + item->scale());
    }
}

void MainWindow::on_actZoomOut_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt <= 0)
    {
        ui->graphicsView->scale(0.9, 0.9);
        return;
    }

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(i);
        item->setScale(-0.1 + item->scale());
    }
}

void MainWindow::on_actRestore_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt <= 0)
    {
        ui->graphicsView->resetTransform(); // 恢复原始矩阵
        return;
    }

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(i);
        item->setScale(1); // item使用resetTransform无效
    }
}

void MainWindow::on_actRotateLeft_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt <= 0)
    {
        ui->graphicsView->rotate(-15);
        return;
    }

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(i);
        item->setRotation(item->rotation() - 15);
    }
}

void MainWindow::on_actRotateRight_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt <= 0)
    {
        ui->graphicsView->rotate(15);
        return;
    }

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(i);
        item->setRotation(item->rotation() + 15);
    }
}

void MainWindow::on_actEditFront_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt <= 0)
    {
        return;
    }

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(i);
        item->setZValue(item->zValue() + 1);
    }
}

void MainWindow::on_actEditBack_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt <= 0)
    {
        return;
    }

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(i);
        item->setZValue(item->zValue() - 1);
    }
}

void MainWindow::on_actGroup_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt < 2)
    {
        return;
    }

    QGraphicsItemGroup *group = new QGraphicsItemGroup;
    scene->addItem(group);

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(0); // item被取消,所以一直是0
        item->setSelected(false);
        group->addToGroup(item);
    }

    group->setFlags(QGraphicsItem::ItemIsFocusable |
                    QGraphicsItem::ItemIsSelectable |
                    QGraphicsItem::ItemIsMovable);
    scene->clearSelection();
    group->setSelected(true);
}

void MainWindow::on_actGroupBreak_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt <= 0)
    {
        return;
    }

    QList<QGraphicsItemGroup*> list;

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(i);

        if(item->type() == QGraphicsItemGroup::Type)
        {
            QGraphicsItemGroup *group = qgraphicsitem_cast<QGraphicsItemGroup*>(item);
            list.append(group);
        }
    }

    foreach (auto gItem, list)
    {
        scene->destroyItemGroup(gItem);
    }
}

void MainWindow::on_actEditDelete_triggered()
{
    int cnt = scene->selectedItems().count();

    if(cnt == 0)
    {
        return;
    }

    for (int i = 0; i < cnt; ++i)
    {
        QGraphicsItem *item = scene->selectedItems().at(0);
        scene->removeItem(item);
    }
}

你可能感兴趣的:(QT,qt)