Qt涂鸦板及其放大简例
简单的涂鸦板:
1.我们再在程序中添加函数。
我们在dialog.h里的public中再添加鼠标移动事件和鼠标释放事件的函数声明:
void mouseMoveEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
在private中添加变量声明:
QPixmap pix;
QPoint lastPoint;
QPoint endPoint;
因为在函数里声明的QPixmap类对象是临时变量,不能存储以前的值,所以为了实现保留上次的绘画结果,我们需要将其设为全局变量。
后两个QPoint变量存储鼠标指针的两个坐标值,我们需要用这两个坐标值完成绘图。
2.在dialog.cpp中进行修改。
在构造函数里进行变量初始化。
resize(600,500); //窗口大小设置为600*500
pix = QPixmap(200,200);
pix.fill(Qt::white);
然后进行其他几个函数的定义:
void Dialog::paintEvent(QPaintEvent *)
{
QPainter pp(&pix);
pp.drawLine(lastPoint,endPoint); //根据鼠标指针前后两个位置就行绘制直线
lastPoint = endPoint; //让前一个坐标值等于后一个坐标值,这样就能实现画出连续的线
QPainter painter(this);
painter.drawPixmap(0,0,pix);
}
void Dialog::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton) //鼠标左键按下
lastPoint = event->pos();
}
void Dialog::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons()&Qt::LeftButton) //鼠标左键按下的同时移动鼠标
{
endPoint = event->pos();
update();
}
}
void Dialog::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton) //鼠标左键释放
{
endPoint = event->pos();
update();
}
}
这里的update()函数,是进行界面重绘,执行该函数时就会执行那个重绘事件函数。
3.这时运行程序,效果如下。
这样简单的涂鸦板程序就完成了。下面我们进行放大后的涂鸦。
放大后再进行涂鸦:
1.添加放大按钮。
在dialog.h中添加头文件声明: #include <QPushButton>
在private中添加变量声明:
int scale;
QPushButton *pushBtn;
然后再在下面写上按钮的槽函数声明:
private slots:
void zoomIn();
2.在dialog.cpp中进行更改。
在构造函数里添加如下代码:
scale =1; //设置初始放大倍数为1,即不放大
pushBtn = new QPushButton(this); //新建按钮对象
pushBtn->setText(tr(“zoomIn”)); //设置按钮显示文本
pushBtn->move(500,450); //设置按钮放置位置
connect(pushBtn,SIGNAL(clicked()),this,SLOT(zoomIn())); //对按钮的单击事件和其槽函数进行关联
这里我们利用代码添加了一个按钮对象,用它来实现放大操作。
再在构造函数以外进行zoomIn()函数的定义:
void Dialog::zoomIn() //按钮单击事件的槽函数
{
scale *=2;
update();
}
3.想让画布的内容放大有两个办法,一个是直接放大画布的坐标,一个是放大窗口的坐标。
我们主要讲解放大窗口坐标。
void Dialog::paintEvent(QPaintEvent *)
{
QPainter pp(&pix);
pp.drawLine(lastPoint,endPoint); //根据鼠标指针前后两个位置绘制直线
lastPoint = endPoint; //让前一个坐标值等于后一个坐标值,这样就能实现画出连续的线
QPainter painter(this);
painter.scale(scale,scale); //进行放大操作
painter.drawPixmap(0,0,pix);
}
这时运行程序。
先随意画一个图形,如下图。
再按下“zoomIn”按钮,进行放大两倍。可以看到图片放大了,效果如下。
这时我们再进行绘图,绘制出的线条已经不能和鼠标指针的轨迹重合了。效果如下图。
看了我的“深入探索Qt的坐标系统”一文,就不难理解出现这个问题的原因了。窗口的坐标扩大了,但是画布的坐标并没有扩大,而我们画图用的坐标值是鼠标指针的,鼠标指针又是获取的窗口的坐标值。现在窗口和画布的同一点的坐标并不相等,所以就出现了这样的问题。
其实解决办法很简单,窗口放大了多少倍,就将获得的鼠标指针的坐标值缩小多少倍就行了。
void Dialog::paintEvent(QPaintEvent *)
{
QPainter pp(&pix);
pp.drawLine(lastPoint/scale,endPoint/scale);
lastPoint = endPoint;
QPainter painter(this);
painter.scale(scale,scale); //进行放大操作
painter.drawPixmap(0,0,pix);
}
运行程序,效果如下:
此时已经能进行正常绘图了。
这种用改变窗口坐标大小来改变画布面积的方法,实际上是有损图片质量的。就像将一张位图放大一样,越放大越不清晰。原因就是,它的像素的个数没有变,如果将可视面积放大,那么单位面积里的像素个数就变少了,所以画质就差了。
下面简单说说另一种方法。
放大画布坐标。
void Dialog::paintEvent(QPaintEvent *)
{
QPainter pp(&pix);
pp.scale(scale,scale);
pp.drawLine(lastPoint/scale,endPoint/scale);
lastPoint = endPoint;
QPainter painter(this);
painter.drawPixmap(0,0,pix);
}
效果如下:
此时,画布中的内容并没有放大,而且画布也没有变大,不是我们想要的,所以我们再更改一下函数。
void Dialog::paintEvent(QPaintEvent *)
{
if(scale!=1) //如果进行放大操作
{
QPixmap copyPix(pix.size()*scale); //临时画布,大小变化了scale倍
QPainter pter(©Pix);
pter.scale(scale,scale);
pter.drawPixmap(0,0,pix); //将以前画布上的内容复制到现在的画布上
pix = copyPix; //将放大后的内容再复制回原来的画布上,这样只传递内容,不传递坐标系
scale =1; //让scale重新置1
}
QPainter pp(&pix);
pp.scale(scale,scale);
pp.drawLine(lastPoint/scale,endPoint/scale);
lastPoint = endPoint;
QPainter painter(this);
painter.drawPixmap(0,0,pix);
}
此时运行效果如下:
这样就好了。可以看到,这样放大后再进行绘制,出来的效果是不同的。
Qt涂鸦板及其放大简例相关推荐
- [转载]Qt涂鸦板程序图文详细教程..Qt涂鸦板程序图文详
原文地址:Qt涂鸦板程序图文详细教程..Qt涂鸦板程序图文详细教程..作者:棰滈櫟鍚 Technorati 标签: QT http://www.yafeilinux.com/?p=379 (说明:这是 ...
- 【Qt】2D绘图之涂鸦板
00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 程序设计(基本功能) 04. 程序设计(放大功能) 05. 程序设计(放大功能) 06. 附录 01. 概述 结合前面所学 ...
- [Qt教程] 第17篇 2D绘图(七)涂鸦板
[Qt教程] 第17篇 2D绘图(七)涂鸦板 楼主 发表于 2013-5-2 21:37:41 | 查看: 1255| 回复: 16 涂鸦板 版权声明 该文章原创于Qter开源社区(www.qter ...
- 【Qt入门第17篇】 2D绘图(七)涂鸦板
导语 通过前面几节的学习,大家应该已经对Qt中2D绘图有了一定的认识,这一节我们将应用前面讲到的内容,编写一个简单的涂鸦板程序,这一节只是实现最基本的鼠标画线功能. 环境:Windows Xp + Q ...
- 第17篇 2D绘图(七)涂鸦板
导语 通过前面几节的学习,大家应该已经对Qt中2D绘图有了一定的认识,这一节我们将应用前面讲到的内容,编写一个简单的涂鸦板程序,这一节只是实现最基本的鼠标画线功能. 环境:Windows Xp + Q ...
- Android应用开发实例篇(1)-----简易涂鸦板
一.概述 这次要做一个简单的涂鸦板应用,以前在Qt上实现过,突然想到要把它在Android上实现,呵呵,既简单又有趣. 二.实现 新建工程MyWall,修改/res/layout/main.xml文件 ...
- oracle供应商导入,AP供应商导入简例.pdf
AP供应商导入简例 Oracle 完全测试记录 供应商导入 吴若童 总述总述 总述总述 供应商供应商接口接口的原理的原理?? 供应商供应商接口接口的原理的原理?? 系统从三个表分别导入供应商.供应商地 ...
- Android RuntimePermissions运行时权限:单个运行时权限申请简例
Android RuntimePermissions运行时权限:单个运行时权限申请简例 Android运行时权限申请的框架结构和步骤比较简单和固定,一般现状代码启动后检查当前的Android SDK版 ...
- UI进阶--Quartz2D和触摸事件的简单使用:简易涂鸦板
需求:实现一个简易的涂鸦板应用,使用鼠标在涂鸦板内拖动即可进行涂鸦,点击保存按钮,可以把完成的涂鸦保存,点击回退按钮可以向后退回一步,点击清空可以让涂鸦板清空. 实现步骤: 1.布局storyboar ...
- 5.3linux下C语言socket网络编程简例
原创文章,转载请注明转载字样和出处,谢谢! 这里给出在Linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后 ...
最新文章
- C指针原理(42)-内存管理与控制
- ZOJ3865:Superbot(BFS) The 15th Zhejiang University Programming Contest
- 十天学会ASP.Net——(2)
- SpringBoot 2.x 集成Redis
- 【Hadoop】Bad connect ack with firstBadLink as ×.×.×.×:50010
- python把cookie分割成字典
- python+Treelite:Sklearn树模型训练迁移到c、java部署
- flutter html 加载_Flutter开发:项目加载本地html文件的步骤
- 现在电脑的主流配置_2019~2020电脑配置清单主流配件(下)
- WebStart啟動程式在關閉時關閉javaw進程
- NSString (NSStringPathExtensions) 类的相关方法和属性梳理
- Mac 移动硬盘没有推出,再插上不显示移动硬盘解决办法
- HDU 2586	How far away ? tarjan算法求LCA
- 求当前时间的三种方法(Java)
- 宝塔面板专业版企业版教程 纯手动 带原版脚本 插件免费用
- Cannot create symlink/symbolic to `xxx': Operation not supported
- Solidity 基础(一)
- 收敛域、收敛区间与收敛半径
- 2018年创翼 开wifi方法 适合电脑小白
- 爱快固件是Linux系统吗,Linux 系统下 VirtualBox 里安装爱快系统 (2.4.4)