基于QT实现的画图板程序的设计与实现论文.docx
《基于QT实现的画图板程序的设计与实现论文.docx》由会员分享,可在线阅读,更多相关《基于QT实现的画图板程序的设计与实现论文.docx(17页珍藏版)》请在冰豆网上搜索。
基于QT实现的画图板程序的设计与实现论文
基于QT实现的画图板程序的设计与实现
学生姓名:
张健指导教师:
张永奎赵文娟储晶凯
内容提要:
本程序通过调用QT提供的BorderLayout,Button,ButtonGroup等根本类进行了简单的界面设计,运用C++中类的继承特性实现对父类方法的调用,运用信号与槽函数的机制,实现绘制根本图形功能,同时可以在翻开的图片上进行二次绘制。
图形界面的各个按钮如“橡皮〞、“铅笔〞、“图形〞等都能实现其画笔线条的大小,颜色是否填充,编辑各种颜色的实现。
关键词:
嵌入式LinuxQT图形用户界面电子画板双缓冲机制
1.引言
计算机图形技术是随着计算机技术在图形处理领域中的应用而开展起来的一门新技术,是伴随着电子计算机及其外围设备的开展而产生的,现已成为计算机应用科学中的一个重要分支,在许多行业中起着越来越大的作用。
该软件功能与Windows下附件中的画图软件有类似功能。
绘制方面的功能主要包括绘制各种图元,包括直线、矩形、椭圆等,用笔或画刷自由绘图。
绘图时可以选择各种颜色,各种线宽。
软件支持保存和读取jpg格式的图形。
该软件的设计思想是面向对象程序设计的思想。
面向对象技术是一个非常实用而强有力的软件开发方法。
它具有许多特色。
一是方法的唯一性,即方法是对软件开发过程所有阶段进行综合考虑得到的。
二是从生存周期的一个阶段到下一个阶段的高度连续性,即在一个阶段所用到的局部与在下一个阶段所使用的局部是衔接的,所使用的技术经过生存期的每一个阶段后不变。
三是面向对象分析(OOA)、面向对象设计(OOD)和面向对象程序设计(OOP)集成到生存期的相应阶段。
1.1研究背景
计算机技术的开展,使人类社会进入了信息化和自动化,计算机智能识别也随着计算机的开展得到了迅速的开展。
特别是图形图像的计算机处理技术更是有了前所未有的进步和应用。
计算机识别也逐渐的从图形图像处理的大环境下别离出来作为一门新的高科技研究领域出现。
画图涉及到的学科很多,包括数字信号处理、工程数学、信息论、运筹学等,它与计算机、自动化、生物学、视觉心理和生理学、人工智能、智能信息处理等众多领域交叉、综合集成,有广泛的应用。
随着操作系统不断的更新换代,其自带的画图板界面及功能也是不断变化着的。
像是xp、vista、win7,它们的画图板的界面布局风格以及功能都有所不同。
这说明,尽管是简简单单的一个操作系统自带画图板,系统设计人员也没有停止对它的不断研究与探索,他们在不断寻找着更人性化、更能满足群众需求的改变。
研究的目的和意义
本选题是设计一个简单的画图软件,能够完成一些简单的画图需求。
在日常生活中,有很多方面都会用到画图来解决阐述一些问题,这就需要借助计算机来进行简单的画图工作,此时就需要一个能简单解决这些问题的画图软件。
现在比拟经常使用的是windows系统下附带的画图软件,它根本上可以满足一些简单的画图需求。
本设计就是按照这个画图软件的思想设计的,使画图软件能到达满足日常画图需求,功耗小且界面人性化。
2.QT技术
QT是用于本地化跨平台应用开发的领先性“框架〞[1]。
QT应用程序接口与工具兼容于所有支持平台,让开发员们掌握一个应用程序接口,便可执行与平台非相关的应用开发与配置。
通过使用QT,开发小组们从主要的“开发平台〞[2],可为主要操作系统创立本地化的应用程序。
QT主要特性
QT是一个跨平台的C++图形用户界面库,由挪威TrollTech公司开发,目前包括QT/X11、基于Framebuffer的QT、快速开发工具QTDesigner以及国际化工具“QTLinguist〞[3]等。
人们所熟知的Linux下面的KDE环境就是基于QT开发而成的。
QT支持“Unix和Linux系统〞[4][5]以及Windows系统。
QT的主要特点有:
面向对象,很容易扩展,并且允许真正的组件编程;QT对各个模块进行了良好的封装,使各模块可重用性较好;优良的跨平台特性,使用QT类编写的程序可以实现“一次编码,到处编译〞,极大的降低了跨平台开发的难度;构件支持,对于对象间通信,QT采用了一种全新并且可选的被称为“信号与槽〞的对象间通信机制,通过一个对象信号的发射,另一个槽函数的响应,使各个对象之间的通信平安而且高效。
QT的这些特点使它非常适合于真正的构件编程,同时使各个组件之间的协同工作变得十分简单,并且QT是直接基于Xlib的,不依赖Motif工具包,所以它的执行效率比一般的基于平台的代码的执行效率要高。
2.2QT编程机制信号与槽机制简介
信号/槽机制是QT的一个中心特征并且也许是QT与其它工具包的最不相同的局部。
在图形用户界面编程中,经常希望一个窗口部件的一个变化被通知给另一个窗口部件。
更一般地,希望任何一类的对象可以和其它对象进行通讯。
QT的信号与槽机制是QT的信号与槽均以函数形式出现,QT的窗口部件有很多预定义的信号,但也可以通过继承来参加自己的信号。
槽就是一个可以被调用处理特定信号的函数。
QT的窗口部件有很多预定义的槽,但是通常的习惯是你可以参加自己的槽,这样你就可以处理你所感兴趣的信号。
可以用connect〔〕函数对需要的信号和槽进行连接。
当对象的内部状态发生改变,信号就被发射。
从某种意义上讲,它们也许对外面的世界感兴趣。
这就是所有的对象通讯时所做的一切。
它不知道也不注意无论有没有东西接收它所发射的信号。
当一个信号被发射,它所连接的槽会被立即执行,信号/槽机制完全不依赖于任何一种图形用户界面的事件回路。
当所有的槽都返回后发射的信号也将返回。
信号与插槽机制并不要求类之间互相知道细节,这样就可以相对容易的开发出代码可高重用的类。
QT的信号和槽的机制可以保证如果你把一个信号和一个槽连接起来,槽会在正确的时间使用信号的参数而被调用。
信号和槽可以使用任何数量、任何类型的参数。
它们是完全类型平安的:
不会再有回调核心转储〔coredump〕。
可以把许多信号和你所希望的单一槽相连,并且一个信号也可以和所期望的许多槽相连。
把一个信号和另一个信号直接相连也是可以的。
总体来看,信号和槽构成了一个强有力的组件编程机制。
如果一个类要使用信号与槽机制,它就必须是从QObject或QObject的子类继承,而且类的定义必须加上Q_OBJECT宏。
signals、slots和emit是QT特有的关键字,分别用来表示信号、槽、和发送信号,移除这些关键字和预处理程序,就可以使用“标准的C++编译器〞[6][7][8]。
槽同其他函数一样也具有访问权限,只是槽的访问权限决定了谁可以和它相连,如一个publicslots:
包含了任何信号都可以相连的槽。
一个protectedslots:
包含了只有这个类和它的子类的信号才能连接的槽。
这就是说这些槽只是类的实现的一局部,而不是它和外界的接口。
一个privateslots:
包含了只有这个类本身的信号可以连接的槽,甚至它的子类都没有获得连接的权利。
3双缓冲机制
3.1双缓冲原理
所谓“双缓冲区〞,故名思义就是要有俩缓冲区〔简称A和B〕。
这俩缓冲区,总是一个用于生产者,另一个用于消费者。
当俩缓冲区都操作完,再进行一次切换〔先前被生产者写入的转为消费者读出,先前消费者读取的转为生产者写入〕。
由于生产者和消费者不会同时操作同一个缓冲区〔不发生冲突〕,所以就不需要在读写每一个数据单元的时候都进行同步/互斥操作。
顺便提一下,这又一次展现了空间换时间的优化思路。
但是光有俩缓冲区还不够。
为了做到“不冲突〞,还得再搞两个互斥锁〔简称La和Lb〕,分别对应俩缓冲区。
生产者或消费者如果要操作某个缓冲区,必须先拥有对应的互斥锁。
3.2双缓冲技术绘图
当要绘制屏幕时,我们只要调用paint函数即可。
其中我们可以使用绘图方法来绘制任何文字图形图像。
可是当我们绘制的东西多了之后,你就会发现又是屏幕上的显示根本不是我们要的结果,很杂乱。
细想想,会知道因为paint函数中,我们是一边绘制一边显示,所以当内容过多,就会产生没绘制完成,就显示到屏幕上的结果。
因此,双缓冲区就提供了一个完美的解决方案。
我们可以在缓冲区2中绘制图像,而是用缓冲区1来输出到屏幕。
这样我们就可以控制绘制和现实的过程,从而防止上面的现象。
双缓冲即在内存中创立一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。
双缓冲实现过程如下:
1、在内存中创立与画布一致的缓冲区
2、在缓冲区画图
3、将缓冲区位图拷贝到当前画布上
4、释放内存缓冲区
4电子画板功能设计与实现
设计实现一个成功的应用程序,不但要有使用的功能配置,也要有有好的用户界面,本节就是对于电子画板程序的设计与实现的简要介绍。
4.1电子画板功能设计
在对软件进行实际设计之前,先对使用过程中用户可能用到或可能需要的功能等进行整理和列一个简要的提纲,具体设计丝路如下:
(1)画板新建功能:
新建初始画板。
(2)画板保存、另存为功能:
在对画板进行编辑之后,可以选择保存或者另存为。
(3)画板的翻开功能:
可以翻开原来编辑并保存过的画板。
(4)画板放大功能:
图片可逐级放大尺寸。
(5)画板缩小功能:
图片可逐级缩小尺寸。
(6)画板复原功能:
画板通过不同尺寸的放大和缩小后,能够复原到初始新建的尺寸大小。
(7)画板清空功能:
画板可以在当前任何状态下进行对当前状态的情空,回到初始新建画板状态。
(8)画板画图工具功能:
画板可以实现选择图形、画笔线宽、画笔颜色等功能。
(9)为用户设计理想的侧边绘图工具栏,并合理安排界面元素布局,使其美观并且方便用户操作。
(10)图片翻开、编辑、保存功能:
可以翻开一些格式的图片,如png、bmp等,并且可以作为画板背景,在其做编辑并且保存。
4.2电子画板界面设计
4电子画板整体结构布局
首先要对设计的电子画板布局,使其含有新建、翻开、保存等功能键,其次要设计工具栏。
最终,电子画板的整体结构如图1所示:
图1电子画板布局结构效果图
4电子画板布局的实现
(1)调用QT中的createMenus()函数,实现菜单栏的布局。
(2)调用QT中的createToolBars()函数,实现工具栏的布局。
(3)将画布添加到布局中。
在电子画板布局过程中需要一个添加一个存放菜单栏、工具栏的窗口类。
(1)在工程中添加新的“C++类〞[9][10][11],类名为Mywindow,以“QMainWindow〞[12]作为基类。
(2)在mywindow.h中声明对象和函数:
classMyWindow:
publicQMainWindow{
Q_OBJECT
public:
MyWindow(QWidget*parent=0);
~MyWindow();
voidcreateMenus();//菜单栏功能函数声明
voidcreateToolBars();//工具栏功能函数声明
voidcreateToolBars1();
protectedslots:
voidnew_slot();
voidopen_slot();
voidsaveAs_slot();//另存为的槽函数
voidsave_slot();//保存的槽函数
private:
PaintArea*paintArea;//绘图区域
QScrollArea*scrollArea;
QToolBar*mainToolBar;
QToolBar*leftToolBar1;
};
4添加画布
画布是真正实现绘图功能的,所以需要在程序中添加一个与绘图有关的类。
(1)在工程中添加新的C++类,类名PaintArea,以QWidget作为基类。
(2)在paint.h中声明对象和函数:
classPaintArea:
publicQWidget
{
public:
PaintArea〔〕;
protected:
voidpaintEvent〔QPaintEvent*〕;//重绘事件
private:
QImageimage;//QImage类对象,用于在其上绘图
QRgbbackColor;//QRgb颜色对象,存储image的背景色
};
(1)在paint.cpp中定义重绘函数:
voidPaintArea:
:
paintEvent〔QPaintEvent*〕{
QPainterpainter〔this〕;
〔0,0,image〕;
}
4.3电子画板涂鸦功能的实现
在画布类中添加一些代码,实现一些根本的涂鸦功能:
(1)在paint.h中做更改。
添加头文件:
#include
#include
在protected中添加函数声明:
voidmousePressEvent〔QMouseEvent*〕;//鼠标按下事件
voidmouseMoveEvent〔QMouseEvent*〕;//鼠标移动事件
voidmouseReleaseEvent〔QMouseEvent*〕;//鼠标释放事件
在private中添加对象声明:
QPointlastPoint,endPoint;//定义两个坐标对象存放鼠标指针的前后两个坐标
(2)在paint.cpp中添加函数的定义。
voidPaintArea:
:
mousePressEvent〔QMouseEvent*event〕{
if〔event->button〔〕==QT:
:
LeftButton〕{//当鼠标左键按下
lastPoint=event->pos〔〕;//获得鼠标指针的当前坐标作为起始坐标
}}
voidPaintArea:
:
mouseMoveEvent〔QMouseEvent*event〕{
if〔event->buttons〔〕&QT:
:
LeftButton〕{//如果鼠标左键按着的同时移动鼠标
lastPoint=event->pos〔〕;//获得鼠标指针的当前坐标作为起始坐标
}}
voidPaintArea:
:
mouseMoveEvent〔QMouseEvent*event〕{
if〔event->buttons〔〕&QT:
:
LeftButton〕{//如果鼠标左键按着的同时移动鼠标
endPoint=event->pos〔〕;//获得鼠标指针的当前坐标作为终止坐标
paint〔image〕;//绘制图形
}}
voidPaintArea:
:
mouseReleaseEvent〔QMouseEvent*event〕{
if〔event->button〔〕==QT:
:
LeftButton〕{//如果鼠标左键释放
endPoint=event->pos〔〕;
paint〔image〕;}}
voidPaintArea:
:
paint〔QImage&theImage〕{
QPainterpp〔&theImage〕;//在theImage上绘图
〔lastPoint,endPoint〕;//由起始坐标和终止坐标绘制直线
lastPoint=endPoint;//让终止坐标变为起始坐标
update〔〕;//进行更新界面显示,可引起窗口重绘事件,重绘窗口
}
这样就能实现涂鸦的功能了,效果如图2所示:
图2实现涂鸦功能
4.4电子画板根本图形的实现
在我们日常用的画图板中有矩形、椭圆、圆角矩形等根本图形,因此为了我们的电子画板能更好的符合人们的需求,需要在程序中添加一些代码,实现这些功能。
在paint.cpp中的鼠标事件中添加以下代码:
switch(shape){
caseLine:
{
QPenpen;
pen.setWidth(penWidth);
pen.setColor(color);//设置画笔的颜色
painter.setPen(pen);
endPoint=event->pos();//记录终点位置
painter.drawLine(lastPoint,endPoint);
lastPoint=endPoint;//更新鼠标当前位置,为下次绘制做准备
break;}
caseNone:
{
QPenpen;
pen.setWidth(penWidth);
pen.setColor(color);//设置画笔的颜色
painter.setPen(pen);
endPoint=event->pos();//记录终点位置
painter.drawLine(lastPoint,endPoint);
lastPoint=endPoint;//更新鼠标当前位置,为下次绘制做准备
break;}
casePen:
{
QPenpen;
pen.setWidth(penWidth);
pen.setColor(color);//设置画笔的颜色
painter.setPen(pen);
endPoint=event->pos();//记录终点位置
painter.drawLine(lastPoint,endPoint);
lastPoint=endPoint;//更新鼠标当前位置,为下次绘制做准备
break;}
caseBrush:
{
QPenpen;
pen.setWidth(brushWidget);
pen.setColor(color);
painter.setPen(pen);
endPoint=event->pos();//记录终点位置
painter.drawLine(lastPoint,endPoint);
lastPoint=endPoint;//更新鼠标当前位置,为下次绘制做准备
break;}
caseRubber:
{
painter.setPen(QPen(Qt:
:
white,20));//橡皮擦其实是画笔颜色为白色,线宽为20的画笔
endPoint=event->pos();
painter.drawLine(lastPoint,endPoint);
lastPoint=endPoint;
break;}
caseRoundRect:
caseRectangle:
caseEllipse:
{
w=event->x()-x;
h=event->y()-y;
break;}}
tempImage=img;
paint(tempImage);
update();}//强迫窗口重绘
4.5实现编辑菜单功能
编辑菜单主要完成图片的一些形状变化操作,所以需要在画布类里添加一些函数和变量来实现这些功能。
(1)在paint.h中添加代码。
在public中添加函数声明:
voidzoomIn〔〕;//放大
voidzoomOut〔〕;//缩小
voidzoom_1〔〕;//复原
voidclear〔〕;//清空
在private中添加变量声明:
qrealscale;//缩放量
(2)在paint.cpp中进行更改。
在构造函数里进行变量初始:
scale=1;
angle=0;
shear=0;
然后进行那几个函数的定义:
voidPaintArea:
:
zoomIn〔〕{
;
update〔〕;
}
voidPaintArea:
:
zoomOut〔〕{
;
update〔〕;
}
voidPaintArea:
:
zoom_1〔〕{
scale=1;
update〔〕;
}
voidPaintArea:
:
clear(){
clearImage=QImage(this->width(),this->height(),QImage:
:
Format_ARGB32);
clearImage.fill(Qt:
:
white);
img=clearImage;
update();
}
这样就能实现画根本图形功能了,效果如图3所示:
图3实现根本图形功能
5.结语
本文着重介绍了基于一个成熟的嵌入式GUI系统即QT所设计的电子画板程序并可以在Linux环境下运行,实现了电子画板的相关根本功能,另外还实现了翻开png、bmp等格式图片在其根底上进行绘图的功能。
总体来说,电子画板的设计能够满足根本的用户需求,不过要成为一款真正能够进入市场的软件,还是有很多的缺陷,同时还需要更多拓展功能的支持。
例如电子画板的界面还需要更进一步整体美化、翻开图片的格式过于单一、无法进行对所画图形的剪切选取、绘图工具的种类不够具体、能够加上自定义颜色功能等等。
通过这次的设计,QT作为一款跨平台的图形用户界面设计软件,还是很适合应用快速开发的,相信会有越来越多的人会参加到QT的研发中来,使它的功能和性能不断完善,并在实际应用中走向成熟。
参考文献
[1]陈英,梁建武.Linux根底及应用教程.水利水电出版社,2021,29-42
[2]倪继利.Qt以及linux操作系统窗口设计.电子工业出版社,2006,45-152
[3]BlakowskiG,SteinmetzR.Amediasynchronizationsurvey:
referencemodel,specification,andcasestudies[J].IEEEJournalSelectedAreasinCommunications,1996,14〔1〕:
5-35
[4]金西,黄汪.嵌入式Linux技术及其应用.计算机应用,2000,20〔7〕:
5-6
[5]刘峥嵘.嵌入式Linux应用开发详解.机械工业出版社,2004,53-68
[6]林锐,韩永泉.高质量程序设计指南:
C++、C语言.电子工业出版社,2007,124-155
[7]JonathanCorbet,AlessandroRubini,GregKoah-Hartman.LinuxDeviceDriver.Jan2005
[8]钱能.C++程序设计教程.清华大学出版社,2006,56-88
[9]任善全,吕强,钱培德等.一个基于QtEmbedded的嵌入式Linux应用程序的实现,计算机应用与软件,2006,2
[10]ISO/IECJTC1/SC29/WG11.IS14496:
Genericcodingofmovingpicturesandassociatedaudioinformation〔MPEG-4〕.ISO/IEC,2000:
10-15
[11]谭浩强.C++面向对象程序设计.清华大学出版社,2006,89-100
[12]王子强,刘海燕,李媛州.Linux下列图形用户界面程序的开发与实现,计算机应用与软件,2005
DesignandImplementationofthedrawingboardproceduresbasedontheQTimplementation
Abstract:
TheBorderLayout,theButton,ButtonGroupandotherbasicclassesprovidedbytheprogrambycallingtheQTconductasimpleinterf