十八Qt 2D绘图八涂鸦板46.docx
- 文档编号:29998560
- 上传时间:2023-08-04
- 格式:DOCX
- 页数:7
- 大小:77.43KB
十八Qt 2D绘图八涂鸦板46.docx
《十八Qt 2D绘图八涂鸦板46.docx》由会员分享,可在线阅读,更多相关《十八Qt 2D绘图八涂鸦板46.docx(7页珍藏版)》请在冰豆网上搜索。
十八Qt2D绘图八涂鸦板46
十八、Qt2D绘图(八)涂鸦板
上面一节我们深入分析了一下Qt的坐标系统,这一节我们在前面程序的基础上稍加改动,设计一个涂鸦板程序。
简单的涂鸦板:
1.我们再在程序中添加函数。
我们在dialog.h里的public中再添加鼠标移动事件和鼠标释放事件的函数声明:
voidmouseMoveEvent(QMouseEvent*);
voidmouseReleaseEvent(QMouseEvent*);
在private中添加变量声明:
QPixmappix;
QPointlastPoint;
QPointendPoint;
因为在函数里声明的QPixmap类对象是临时变量,不能存储以前的值,所以为了实现保留上次的绘画结果,我们需要将其设为全局变量。
后两个QPoint变量存储鼠标指针的两个坐标值,我们需要用这两个坐标值完成绘图。
2.在dialog.cpp中进行修改。
在构造函数里进行变量初始化。
resize(600,500); //窗口大小设置为600*500
pix=QPixmap(200,200);
pix.fill(Qt:
:
white);
然后进行其他几个函数的定义:
voidDialog:
:
paintEvent(QPaintEvent*)
{
QPainterpp(&pix);
pp.drawLine(lastPoint,endPoint); //根据鼠标指针前后两个位置就行绘制直线
lastPoint=endPoint; //让前一个坐标值等于后一个坐标值,这样就能实现画出连续的线
QPainterpainter(this);
painter.drawPixmap(0,0,pix);
}
voidDialog:
:
mousePressEvent(QMouseEvent*event)
{
if(event->button()==Qt:
:
LeftButton)//鼠标左键按下
lastPoint=event->pos();
}
voidDialog:
:
mouseMoveEvent(QMouseEvent*event)
{
if(event->buttons()&Qt:
:
LeftButton)//鼠标左键按下的同时移动鼠标
{
endPoint=event->pos();
update();
}
}
voidDialog:
:
mouseReleaseEvent(QMouseEvent*event)
{
if(event->button()==Qt:
:
LeftButton)//鼠标左键释放
{
endPoint=event->pos();
update();
}
}
这里的update()函数,是进行界面重绘,执行该函数时就会执行那个重绘事件函数。
3.这时运行程序,效果如下。
(点击图片可将其放大)
这样简单的涂鸦板程序就完成了。
下面我们进行放大后的涂鸦。
放大后再进行涂鸦:
1.添加放大按钮。
在dialog.h中添加头文件声明:
#include
在private中添加变量声明:
intscale;
QPushButton*pushBtn;
然后再在下面写上按钮的槽函数声明:
privateslots:
voidzoomIn();
2.在dialog.cpp中进行更改。
在构造函数里添加如下代码:
scale=1; //设置初始放大倍数为1,即不放大
pushBtn=newQPushButton(this);//新建按钮对象
pushBtn->setText(tr(“zoomIn”)); //设置按钮显示文本
pushBtn->move(500,450); //设置按钮放置位置
connect(pushBtn,SIGNAL(clicked()),this,SLOT(zoomIn()));//对按钮的单击事件和其槽函数进行关联
这里我们利用代码添加了一个按钮对象,用它来实现放大操作。
再在构造函数以外进行zoomIn()函数的定义:
voidDialog:
:
zoomIn()//按钮单击事件的槽函数
{
scale*=2;
update();
}
3.通过上一节的学习,我们应该已经知道想让画布的内容放大有两个办法,一个是直接放大画布的坐标,一个是放大窗口的坐标。
我们主要讲解放大窗口坐标。
voidDialog:
:
paintEvent(QPaintEvent*)
{
QPainterpp(&pix);
pp.drawLine(lastPoint,endPoint); //根据鼠标指针前后两个位置就行绘制直线
lastPoint=endPoint; //让前一个坐标值等于后一个坐标值,这样就能实现画出连续的线
QPainterpainter(this);
painter.scale(scale,scale);//进行放大操作
painter.drawPixmap(0,0,pix);
}
这时运行程序。
先随意画一个图形,如下图。
再按下“zoomIn”按钮,进行放大两倍。
可以看到图片放大了,效果如下。
这时我们再进行绘图,绘制出的线条已经不能和鼠标指针的轨迹重合了。
效果如下图。
有了前面一节的知识,我们就不难理解出现这个问题的原因了。
窗口的坐标扩大了,但是画布的坐标并没有扩大,而我们画图用的坐标值是鼠标指针的,鼠标指针又是获取的窗口的坐标值。
现在窗口和画布的同一点的坐标并不相等,所以就出现了这样的问题。
其实解决办法很简单,窗口放大了多少倍,就将获得的鼠标指针的坐标值缩小多少倍就行了。
voidDialog:
:
paintEvent(QPaintEvent*)
{
QPainterpp(&pix);
pp.drawLine(lastPoint/scale,endPoint/scale);
lastPoint=endPoint;
QPainterpainter(this);
painter.scale(scale,scale);//进行放大操作
painter.drawPixmap(0,0,pix);
}
运行程序,效果如下:
此时已经能进行正常绘图了。
这种用改变窗口坐标大小来改变画布面积的方法,实际上是有损图片质量的。
就像将一张位图放大一样,越放大越不清晰。
原因就是,它的像素的个数没有变,如果将可视面积放大,那么单位面积里的像素个数就变少了,所以画质就差了。
下面我们简单说说另一种方法。
放大画布坐标。
voidDialog:
:
paintEvent(QPaintEvent*)
{
QPainterpp(&pix);
pp.scale(scale,scale);
pp.drawLine(lastPoint/scale,endPoint/scale);
lastPoint=endPoint;
QPainterpainter(this);
painter.drawPixmap(0,0,pix);
}
效果如下:
此时,画布中的内容并没有放大,而且画布也没有变大,不是我们想要的,所以我们再更改一下函数。
voidDialog:
:
paintEvent(QPaintEvent*)
{
if(scale!
=1)//如果进行放大操作
{
QPixmapcopyPix(pix.size()*scale);//临时画布,大小变化了scale倍
QPainterpter(©Pix);
pter.scale(scale,scale);
pter.drawPixmap(0,0,pix); //将以前画布上的内容复制到现在的画布上
pix=copyPix; //将放大后的内容再复制回原来的画布上,这样只传递内容,不传递坐标系
scale=1;//让scale重新置1
}
QPainterpp(&pix);
pp.scale(scale,scale);
pp.drawLine(lastPoint/scale,endPoint/scale);
lastPoint=endPoint;
QPainterpainter(this);
painter.drawPixmap(0,0,pix);
}
此时运行效果如下:
这样就好了。
可以看到,这样放大后再进行绘制,出来的效果是不同的。
我们就讲到这里,如果你有兴趣,可以接着研究!
怎么应用上面讲到的内容,你可以查看Qt涂鸦板程序图文详细教程。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 十八Qt 2D绘图八涂鸦板46 十八 Qt 绘图 涂鸦 46
