简单的涂鸦板:

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涂鸦板及其放大简例相关推荐

  1. [转载]Qt涂鸦板程序图文详细教程..Qt涂鸦板程序图文详

    原文地址:Qt涂鸦板程序图文详细教程..Qt涂鸦板程序图文详细教程..作者:棰滈櫟鍚 Technorati 标签: QT http://www.yafeilinux.com/?p=379 (说明:这是 ...

  2. 【Qt】2D绘图之涂鸦板

    00. 目录 文章目录 00. 目录 01. 概述 02. 开发环境 03. 程序设计(基本功能) 04. 程序设计(放大功能) 05. 程序设计(放大功能) 06. 附录 01. 概述 结合前面所学 ...

  3. [Qt教程] 第17篇 2D绘图(七)涂鸦板

    [Qt教程] 第17篇 2D绘图(七)涂鸦板 楼主  发表于 2013-5-2 21:37:41 | 查看: 1255| 回复: 16 涂鸦板 版权声明 该文章原创于Qter开源社区(www.qter ...

  4. 【Qt入门第17篇】 2D绘图(七)涂鸦板

    导语 通过前面几节的学习,大家应该已经对Qt中2D绘图有了一定的认识,这一节我们将应用前面讲到的内容,编写一个简单的涂鸦板程序,这一节只是实现最基本的鼠标画线功能. 环境:Windows Xp + Q ...

  5. 第17篇 2D绘图(七)涂鸦板

    导语 通过前面几节的学习,大家应该已经对Qt中2D绘图有了一定的认识,这一节我们将应用前面讲到的内容,编写一个简单的涂鸦板程序,这一节只是实现最基本的鼠标画线功能. 环境:Windows Xp + Q ...

  6. Android应用开发实例篇(1)-----简易涂鸦板

    一.概述 这次要做一个简单的涂鸦板应用,以前在Qt上实现过,突然想到要把它在Android上实现,呵呵,既简单又有趣. 二.实现 新建工程MyWall,修改/res/layout/main.xml文件 ...

  7. oracle供应商导入,AP供应商导入简例.pdf

    AP供应商导入简例 Oracle 完全测试记录 供应商导入 吴若童 总述总述 总述总述 供应商供应商接口接口的原理的原理?? 供应商供应商接口接口的原理的原理?? 系统从三个表分别导入供应商.供应商地 ...

  8. Android RuntimePermissions运行时权限:单个运行时权限申请简例

    Android RuntimePermissions运行时权限:单个运行时权限申请简例 Android运行时权限申请的框架结构和步骤比较简单和固定,一般现状代码启动后检查当前的Android SDK版 ...

  9. UI进阶--Quartz2D和触摸事件的简单使用:简易涂鸦板

    需求:实现一个简易的涂鸦板应用,使用鼠标在涂鸦板内拖动即可进行涂鸦,点击保存按钮,可以把完成的涂鸦保存,点击回退按钮可以向后退回一步,点击清空可以让涂鸦板清空. 实现步骤: 1.布局storyboar ...

  10. 5.3linux下C语言socket网络编程简例

    原创文章,转载请注明转载字样和出处,谢谢! 这里给出在Linux下的简单socket网络编程的实例,使用tcp协议进行通信,服务端进行监听,在收到客户端的连接后,发送数据给客户端:客户端在接受到数据后 ...

最新文章

  1. C指针原理(42)-内存管理与控制
  2. ZOJ3865:Superbot(BFS) The 15th Zhejiang University Programming Contest
  3. 十天学会ASP.Net——(2)
  4. SpringBoot 2.x 集成Redis
  5. 【Hadoop】Bad connect ack with firstBadLink as ×.×.×.×:50010
  6. python把cookie分割成字典
  7. python+Treelite:Sklearn树模型训练迁移到c、java部署
  8. flutter html 加载_Flutter开发:项目加载本地html文件的步骤
  9. 现在电脑的主流配置_2019~2020电脑配置清单主流配件(下)
  10. WebStart啟動程式在關閉時關閉javaw進程
  11. NSString (NSStringPathExtensions) 类的相关方法和属性梳理
  12. Mac 移动硬盘没有推出,再插上不显示移动硬盘解决办法
  13. HDU 2586 How far away ? tarjan算法求LCA
  14. 求当前时间的三种方法(Java)
  15. 宝塔面板专业版企业版教程 纯手动 带原版脚本 插件免费用
  16. Cannot create symlink/symbolic to `xxx': Operation not supported
  17. Solidity 基础(一)
  18. 收敛域、收敛区间与收敛半径
  19. 2018年创翼 开wifi方法 适合电脑小白
  20. 爱快固件是Linux系统吗,Linux 系统下 VirtualBox 里安装爱快系统 (2.4.4)

热门文章

  1. 从事java开发工作三年的感想
  2. mac下制作windows启动U盘
  3. 自然辩证法概论国科大开卷考试
  4. SpringBoot 深入浅出
  5. WORD打印出现错误,未定义书签.
  6. 删除EFI系统分区(ESP)后Windows无法启动,重建引导分区并修复启动的过程
  7. 旁路电容和去偶电容Bypass and Decouple
  8. Toast的几种用法
  9. [Tushare] 通过复权因子计算前复权价格、后复权价格
  10. 今日金融词汇---股价复权,是什么?