简易绘图程序

综合实例开发:简易绘图程序

功能需求:

  • 自由图形绘制
  • 基本图形绘制 (直线,矩形,椭圆)
  • 能够选择图形绘制颜色

简易绘图程序运行截图

界面解决方案

1. 以 QWidget 为基类创建绘图主窗口

2. 使用 QGroupBox 创建图形设置区域

3. 使用单选按钮 QRadioBox 实现目标图形的选择

4. 使用组合框 QComBox 实现绘图颜色的选择

问题

如何实现自由绘图?

分析

自由绘图的本质是跟踪鼠标的移动轨迹;因此,必须考虑什么时候开始?什么时候结束?如何记录鼠标移动?

提示一

从绘图参数的角度,可以将已绘制结束的图形与正在绘制的图形分开处理。

提示二

自由绘图必须记录鼠标移动时经过的所有点坐标;因此绘图参数必须有能力保存多个坐标值。

自由绘图解决方案

问题 

如何实现基础图形动态绘制?

分析

基础图形的目标是固定的,但是开始点和结束点的不同会导致最终形状的差异;因此鼠标移动时根据当前坐标实时绘图,鼠标松开时确定最终图形。

提示三

基本图形绘制需要在鼠标按下并移动时进行动态绘图;但是,无论何时都只需要记录两个坐标值。

基础图形绘制解决方案

图形绘制

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QRadioButton>
#include <QComboBox>
#include <QGroupBox>
#include <QHBoxLayout>
#include <QList>
#include <QPoint>

enum DrawType
{
    NONE,
    FREE,
    LINE,
    RECT,
    ELLIPSE
};


class Widget : public QWidget
{
    Q_OBJECT
private:
    struct DrawParam
    {
        DrawType type;
        Qt::GlobalColor color;
        QList<QPoint> points;
    };

    QRadioButton m_freeBtn;
    QRadioButton m_lineBtn;
    QRadioButton m_rectBtn;
    QRadioButton m_ellispeBtn;
    QComboBox m_colorBox;
    QGroupBox m_grpBox;
    QList<DrawParam> m_drawList;
    DrawParam m_current;

protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);

public:
    Widget(QWidget *parent = nullptr);

    DrawType drawType()
    {
        DrawType ret = NONE;

        if(m_freeBtn.isChecked())       ret = FREE;
        if(m_lineBtn.isChecked())       ret = LINE;
        if(m_rectBtn.isChecked())       ret = RECT;
        if(m_ellispeBtn.isChecked())    ret = ELLIPSE;

        return ret;
    }

    Qt::GlobalColor drawColor()
    {
        Qt::GlobalColor ret = Qt::black;

        if(m_colorBox.currentText() == "Black")     ret = Qt::black;
        if(m_colorBox.currentText() == "Blue")      ret = Qt::blue;
        if(m_colorBox.currentText() == "Green")     ret = Qt::green;
        if(m_colorBox.currentText() == "Red")       ret = Qt::red;
        if(m_colorBox.currentText() == "Yellow")    ret = Qt::yellow;

        return ret;
    }

    void draw(QPainter &painter, DrawParam &p);
    void append(QPoint p);

    ~Widget();
};
#endif // WIDGET_H

Widget.cpp

#include "Widget.h"
#include <QMouseEvent>
#include <QPainter>
#include <QPen>
#include <QBrush>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    m_grpBox.setParent(this);
    m_grpBox.resize(800, 70);
    m_grpBox.move(20, 20);
    m_grpBox.setTitle("Setting");

    m_freeBtn.setParent(&m_grpBox);
    m_freeBtn.resize(60, 20);
    m_freeBtn.setText("Free");
    m_freeBtn.setChecked(true);

    m_lineBtn.setParent(&m_grpBox);
    m_lineBtn.resize(60, 20);
    m_lineBtn.setText("Line");

    m_rectBtn.setParent(&m_grpBox);
    m_rectBtn.resize(60, 20);
    m_rectBtn.setText("Rect");

    m_ellispeBtn.setParent(&m_grpBox);
    m_ellispeBtn.resize(60, 20);
    m_ellispeBtn.setText("Ellipse");

    m_colorBox.addItem("Black");
    m_colorBox.addItem("Blue");
    m_colorBox.addItem("Green");
    m_colorBox.addItem("Red");
    m_colorBox.addItem("Yellow");

    QHBoxLayout* layout = new QHBoxLayout();

    layout->addWidget(&m_freeBtn);
    layout->addWidget(&m_lineBtn);
    layout->addWidget(&m_rectBtn);
    layout->addWidget(&m_ellispeBtn);
    layout->addWidget(&m_colorBox);

    m_grpBox.setLayout(layout);

    m_current.type = NONE;
    m_current.color = Qt::white;
    m_current.points.clear();

    resize(840, 600);
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    m_current.type = drawType();
    m_current.color = drawColor();

    append(event->pos());
}

void Widget::mouseMoveEvent(QMouseEvent *event)
{
    append(event->pos());

    update();
}

void Widget::mouseReleaseEvent(QMouseEvent *event)
{
    append(event->pos());

    m_drawList.append(m_current);

    m_current.type = NONE;
    m_current.color = Qt::white;
    m_current.points.clear();

    update();
}

void Widget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    for(int i = 0; i < m_drawList.count(); i++)
    {
        draw(painter, m_drawList[i]);
    }

    draw(painter, m_current);
}

void Widget::append(QPoint p)
{
    if(m_current.type != NONE)
    {
        if(m_current.type == FREE)
        {
            m_current.points.append(p);
        }
        else
        {
            if(m_current.points.count() == 2)
            {
                m_current.points.removeLast();
            }

            m_current.points.append(p);
        }
    }
}


void Widget::draw(QPainter &painter, DrawParam &p)
{
    painter.setPen(p.color);
    painter.setBrush(p.color);

    if(p.type != NONE && (p.points.count() >= 2))
    {
        int x = (p.points[0].x() < p.points[1].x() ? p.points[0].x() : p.points[1].x());
        int y = (p.points[0].y() < p.points[1].y() ? p.points[0].y() : p.points[1].y());
        int w = qAbs(p.points[0].x() - p.points[1].x());
        int h = qAbs(p.points[0].y() - p.points[1].y());

        switch (p.type)
        {
        case FREE:
            for(int i = 0; i < p.points.count() - 1; i++)
            {
                painter.drawLine(p.points[i], p.points[i + 1]);
            }
            break;

        case LINE:
            painter.drawLine(p.points[0], p.points[1]);
            break;

        case RECT:
            painter.drawRect(x, y, w, h);
            break;

        case ELLIPSE:
            painter.drawEllipse(x, y, w, h);
            break;

        default:
            break;
        }
    }
}

Widget::~Widget()
{
}

程序运行结果如下所示:

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值