Qt涂鸦板程序图文详细教程

2014年10月22日 7615点热度 1人点赞 0条评论

说明:这是我们Qt系列文章的一个例子,请先学习2D绘图部分内容,再学习本教程

前面学习了Qt 2D绘图的基本知识,现在我们将所学习的知识进行一下综合,设计一个简单的画图软件。
因为前面已经有了记事本的例子,所以这里对一些细节知识将不会多讲。而且,这只是个例子,说是软件,其实只是个较大点的程序而已,并不是实际的项目,所以通过这个例子,我们主要为了掌握一个方法和两个知识点。

一个方法:写较复杂程序的方法。
两个知识点:文件菜单的功能实现和利用双缓冲进行绘图。
这个例子共分为三部分进行介绍:
第一部分:进行软件界面的设计。其中一些知识可以参考我博客中的Qt教程四。
第二部分:实现基本的功能,这里会再次详细介绍文件菜单中新建,打开,保存,另存为,关闭等菜单的功能实现。这里你可以参考我博客中的Qt教程六。
第三部分:我们在这里会详细讲解所谓的双缓冲绘图,利用它实现图形(例如矩形,椭圆)的交互式绘制。

第一部分:设计界面

在windows上自带了画图软件,在Qt Creator中也有个绘图软件的例子scribble example,你可以在帮助中进行查看。
而现在我们要写的绘图程序的例子,也应该包含这些功能,如绘画涂鸦,添加直线或矩形等常用图形,可以插入图片,在图片上进行绘画,可以让它缩放旋转拉伸等。想到了这些功能,我们就可以设计软件的界面了。

一.设计菜单

  1. 在QtCreator中新建Qt4 Gui Application工程,我这里使用的工程名为paint,使用默认的QMainWindow作为主窗口。
  2. 为了让程序中可以使用中文,我们先在main.cpp中加入头文件#include <QTextCodec>
    并加入下面一行代码:QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
  3. 打开mainwindow.ui,先设计菜单。依次是文件菜单,编辑菜单,工具菜单和帮助菜单。其内容分别如下:
    文件菜单
    Qt涂鸦板程序图文详细教程
    编辑菜单
    Qt涂鸦板程序图文详细教程
    工具菜单
    Qt涂鸦板程序图文详细教程
    帮助菜单
    Qt涂鸦板程序图文详细教程
  4. 向工程中添加资源文件,向其中添加要使用的菜单图标。
    添加完后记着保存一下资源文件,不然的话,在资源管理器中可能看不到添加的图标。
  5. 打开动作编辑器Action Editor,编辑已添加的菜单动作。
    Qt涂鸦板程序图文详细教程
    我们下面只介绍其中“新建”菜单的编辑,其余菜单照做就行了。
    双击action_N,弹出如下对话框:
    Qt涂鸦板程序图文详细教程
    单击Icon后面的按钮,弹出资源管理器:
    Qt涂鸦板程序图文详细教程
    我们点击上面的Reload,便能显示出我们已经添加的图标,我们选中其中的新建菜单的图标,点击Ok确认,如下图所示:
    Qt涂鸦板程序图文详细教程
    然后我们再在右面的属性窗口中更改statusTip的内容为“新建文件”,这样在鼠标放在新建菜单上是,状态栏就会显示“新建文件”。如下图:
    Qt涂鸦板程序图文详细教程
    我们按照同样的方法设置其它菜单,设置完成后如下图所示:
    Qt涂鸦板程序图文详细教程
  6. 我们把其中的一些图标放到工具栏上,如下图所示:
    Qt涂鸦板程序图文详细教程
    这样就完成了菜单的设计。

二.添加绘图工具栏

我们这里的绘图工具栏使用的是一种叫做Dock的窗口,它与其它窗口的不同就是它可以在其父窗口中浮动,也可以停靠在父窗口的边界,就像一个工具栏一样。

  1. 我们在左边的部件栏中找到Dock Widget,将其拖入到设计区。
    添加后它默认在左边框上停靠着。如下图:
    Qt涂鸦板程序图文详细教程
  2. 我们在其属性栏里将其windowTitle改为“画图工具”。
  3. 向其中拖入相关部件,效果如下图:
    Qt涂鸦板程序图文详细教程
    其中,画笔线宽下的部件为Spin Box,其属性中的objectNamepenWidthSpinBox,属性栏最下面的minimum属性改为1,即最小值为1。
    其余部件均为组合框ComboBox,objectName依次为:
    选择图形:shapeComboBox
    画笔类型:penStyleComboBox
    画笔颜色:penColorComboBox
    填充颜色:brushColorComboBox
    Qt涂鸦板程序图文详细教程
  4. 我们给选择框添加条目。
    右击“选择图形”下面的组合框,弹出菜单,如下:
    Qt涂鸦板程序图文详细教程
    我们点击Edit Items菜单,弹出下面的条目编辑框,我们点击“+”按钮,添加新的条目:
    Qt涂鸦板程序图文详细教程
    我们依次添加“”“直线”“矩形”“椭圆”四个条目,如下所示:
    Qt涂鸦板程序图文详细教程
    同样的我们给“画笔类型“下的组合框添加两个条目“实线”和“点线”。两个颜色组合框的条目以后再添加。
  5. 最后可以让所有部件处于一个网格布局管理器中。
    此时运行程序,效果如下:
    Qt涂鸦板程序图文详细教程
    拖动画图工具栏后效果如下:
    Qt涂鸦板程序图文详细教程

三.添加画布

因为画布是真正实现绘图功能的,所以我们新建一个类来实现所有跟绘图有关的功能。这里先进行操作,对于一些内容到后面我们会详细解释的。

  1. 往工程中添加新的C++类,类名为PaintArea,以QWidget作为基类,如下所示:
    Qt涂鸦板程序图文详细教程
    Qt涂鸦板程序图文详细教程
    2.在paintArea.h中声明对象和函数。
    我们这里使用了QImage类对象进行绘图,其实使用以前讲过的QPixmap类对象也是可以的。
class PaintArea : public QWidget
{
public:
    PaintArea();
protected:
    void paintEvent(QPaintEvent *);   //重绘事件
private:
    QImage image;    //QImage类对象,用于在其上绘图
    QRgb backColor;  //QRgb颜色对象,存储image的背景色
};
  1. paintarea.cpp中的构造函数里初始化对象。
    先加入头文件声明:#include <QPainter>
    再更改构造函数:
PaintArea::PaintArea()
{
    image = QImage(400,300,QImage::Format_RGB32);  //画布的初始化大小设为400*300,使用32位颜色
    backColor = qRgb(255,255,255);    //画布初始化背景色使用白色
    image.fill(backColor);
}
  1. 在paintarea.cpp中定义重绘函数。
void PaintArea::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.drawImage(0,0,image);
}
  1. 将画布添加到主界面的中心区。
    因为以后可能要使用很大的画布,这样为了使画布很大时还能显示,我们需要加入滚动条,所以这里使用了QScrollArea类对象,它提供了横向和纵向的滚动条,如果你有兴趣,可以在帮助中查看它的介绍。
    首先,在mainwindow.h文件中进行如下操作:
    添加头文件声明:
#include “paintarea.h”
#include <QScrollArea>
 在下面的`private`中添加对象的声明:
     `PaintArea *area;`
     `QScrollArea *scrollArea;`
 然后在`mainwindow.cpp`文件中的构造函数里添加代码:
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    resize(700,500);   //主窗口大小设为700*500
    area = new PaintArea;
    scrollArea = new QScrollArea;
    scrollArea->setBackgroundRole(QPalette::Dark);   //scrollArea对象的背景色设为Dark
    scrollArea->setWidget(area);     //将画布添加到scrollArea
    scrollArea->widget()->setMinimumSize(800,600);  //scrollArea初始化大小设为800*600
    setCentralWidget(scrollArea);    //scrollArea加入到主窗口的中心区
}

这时运行程序,效果如下:
Qt涂鸦板程序图文详细教程

四.实现涂鸦的功能

我们在画布类中添加一些代码,实现最基本的涂鸦功能。

  1. paintarea.h中做更改。
    添加头文件:
    #include <QMouseEvent>
    #include <QPoint>
    protected中添加函数声明:
    void mousePressEvent(QMouseEvent *); //鼠标按下事件
    void mouseMoveEvent(QMouseEvent *); //鼠标移动事件
    void mouseReleaseEvent(QMouseEvent *); //鼠标释放事件
    private中添加对象声明:
    QPoint lastPoint,endPoint; //定义两个坐标对象存放鼠标指针的前后两个坐标
  2. paintarea.cpp中添加函数的定义。
void PaintArea::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)  //当鼠标左键按下
    {
        lastPoint = event->pos();   //获得鼠标指针的当前坐标作为起始坐标
    }
}
void PaintArea::mouseMoveEvent(QMouseEvent *event)
{
    if(event->buttons()&Qt::LeftButton)   //如果鼠标左键按着的同时移动鼠标
    {
        endPoint = event->pos();  //获得鼠标指针的当前坐标作为终止坐标
        paint(image);   //绘制图形
    }
}
void PaintArea::mouseReleaseEvent(QMouseEvent *event)
{
    if(event->button() == Qt::LeftButton)   //如果鼠标左键释放
    {
        endPoint = event->pos();  
        paint(image);
    }
}
void PaintArea::paint(QImage &theImage)
{
    QPainter pp(&theImage);   //theImage上绘图
    pp.drawLine(lastPoint,endPoint);   //由起始坐标和终止坐标绘制直线
    lastPoint = endPoint;  //让终止坐标变为起始坐标
    update();   //进行更新界面显示,可引起窗口重绘事件,重绘窗口
}

这样,再次运行程序就能实现涂鸦的功能了,效果如下:
Qt涂鸦板程序图文详细教程

Sollyu

保持饥渴的专注,追求最佳的品质