范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

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

  导语
  通过前面几节的学习,大家应该已经对Qt中2D绘图有了一定的认识,这一节我们将应用前面讲到的内容,编写一个简单的涂鸦板程序,这一节只是实现最基本的鼠标画线功能。
  环境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2  目录一、实现涂鸦板  二、实现放大功能  正文
  一、实现涂鸦板
  1.新建Qt Gui应用,项目名称为 pianter_3  ,基类这次还用 QDialog  ,类名保持 Dialog  不变即可。
  2.到 dialog.h  文件中,先添加头文件包含: #include
  然后添加几个函数的声明:  protected:     void paintEvent(QPaintEvent *);     void mousePressEvent(QMouseEvent *);     void mouseMoveEvent(QMouseEvent *);     void mouseReleaseEvent(QMouseEvent *);
  第一个是绘制事件处理函数,后面分别是鼠标按下、移动和释放事件的处理函数。
  下面再添加几个 private  私有变量声明:  QPixmap pix; QPoint lastPoint; QPoint endPoint;
  因为在函数里声明的 QPixmap  类对象是临时变量,不能存储以前的值,为了实现保留上次的绘画结果,我们需要将其设为全局变量。后面两个 QPoint  变量存储鼠标指针的两个坐标值,我们需要用这两个坐标值完成绘图。
  2.到 dialog.cpp  文件中,先添加头文件包含: #include
  然后在构造函数中添加如下初始代码:  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(); //进行绘制              } }
  当鼠标移动时获得结束点,并更新绘制。调用 update()  函数会执行 paintEvent()  函数进行重新绘制。  void Dialog::mouseReleaseEvent(QMouseEvent *event) {                if(event->button() == Qt::LeftButton) //鼠标左键释放                  {                               endPoint = event->pos();                               update();                  } }
  当鼠标按键释放时也进行重绘。
  现在运行程序,使用鼠标在白色画布上进行绘制,发现已经实现了简单的涂鸦板功能,效果如下图所示。
  二、实现放大功能
  前面已经实现了简单的绘制功能,下面我们将实现放大功能,将画布放大后继续进行涂鸦。这里将使用两种方法来实现,也是对上一节坐标系统后面的问题的更进一步的应用实践。
  1.添加放大按钮。到 dialog.h  文件中,先添加头文件:  #include 
  然后添加下面 private  私有变量声明:  qreal scale; QPushButton *button;
  最后再添加一个私有槽声明:  private slots:     void zoomIn();
  2.到 dialog.cpp  文件中,先在构造函数中添加如下代码:  //设置初始放大倍数为1,即不放大 scale =1; //新建按钮对象 button = new QPushButton(this); //设置按钮显示文本 button->setText(tr("zoomIn")); //设置按钮放置位置 button->move(500, 450); //对按钮的单击事件和其槽函数进行关联 connect(button, SIGNAL(clicked()), this, SLOT(zoomIn()));
  这里使用代码创建了一个按钮对象,并将其单击信号关联到了放大槽上,也就是说按下这个按钮,就会执行 zoomIn()  槽。
  3.下面添加 zoomIn()  的定义:  void Dialog::zoomIn() {     scale *=2;     update(); }
  这里我们让每按下这个按钮,放大值都扩大两倍。后面调用 update()  函数来更新显示。
  4.通过上一节的学习,我们应该已经知道想让画布的内容放大有两个办法,一个是直接放大画布的坐标系统,一个是放大窗口的坐标系统。下面我们先来放大窗口的坐标系统。更改 paintEvent()  函数如下:  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  按钮,效果如下图所示。
  现在再用鼠标进行绘制,发现图形已经不能和鼠标轨迹重合了,效果如下图所示。
  有了前面一节的知识,就不难理解出现这个问题的原因了。窗口的坐标扩大了,但是画布的坐标并没有扩大,而我们画图用的坐标值是鼠标指针的,鼠标指针又是获取的窗口的坐标值。现在窗口和画布的同一点的坐标并不相等,所以就出现了这样的问题。
  其实解决办法很简单,窗口放大了多少倍,就将获得的鼠标指针的坐标值缩小多少倍就行了。我们将 paintEvent()  函数更改如下:  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); }
  运行程序,效果如下图所示。可以看到,已经能够在放大以后继续绘图了。
  这种用改变窗口坐标大小来改变画布面积的方法,实际上是有损图片质量的。就像将一张位图放大一样,越放大越不清晰。原因就是,它的像素的个数没有变,如果将可视面积放大,那么单位面积里的像素个数就变少了,所以画质就差了。
  5.方法二。扩大画布坐标系统。先将 paintEvent()  更改如下:  void Dialog::paintEvent(QPaintEvent *) {     QPainter pp(&pix);     pp.scale(scale, scale);     pp.drawLine(lastPoint,endPoint);     lastPoint = endPoint;     QPainter painter(this);     painter.drawPixmap(0, 0, pix); }
  这时运行程序,先进行绘制,然后点击 zoomIn  按钮,发现以前的内容并没有放大,而当我们再次绘画时,发现鼠标指针和绘制的线条又不重合了。效果如下图所示。
  这并不是我们想要的结果,为了实现按下放大按钮,画布和图形都进行放大,我们可以使用缓冲画布(就是一个辅助画布)来实现。将 paintEvent()  函数内容更改如下。  void Dialog::paintEvent(QPaintEvent *) {     if(scale!=1) //如果进行放大操作     {        //临时画布,大小变化了scale倍        QPixmap copyPix(pix.size()*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); }
  现在运行程序,效果如下图所示。
  结语
  本节讲到的涂鸦板,只是为了实践前面的知识,起到抛砖引玉的作用。大家可以根据自己的理解继续探究下去。在下一节,我们将讲解怎样在涂鸦板上绘制出矩形、椭圆等图形。

1986年非洲杀人湖,一夜夺走1700条人命,将水抽干揪出凶手今天我们要讲的,正是位于喀麦隆西北部的三大杀人湖之一的尼奥斯湖,这个看起来美丽无比的湖泊,曾经在一夜之间,先后夺去了1700条人命死神之云尼奥斯湖的地理风貌都十分诱人,景色美不胜收昆明天空出现金光闪闪的建筑,分析不是海市蜃楼11月12日,云南昆明的天空中出现了不可思议的一幕,一座巨大的建筑物似乎悬浮在天空中,金光闪闪,就像传说中的南天门那样。那么,这究竟是怎么回事呢?是不是海市蜃楼呢?看到这样的景象,新能源货车利好政策频现,燃油车未来发展空间几何?随着近几年国家对环保重视程度的不断提高,货运车新能源化也逐渐成为一种趋势。尤其是在其路权不断放开的大背景下,新能源物流车正在逐渐崛起成为城配运输的新宠。新能源货车路权不断开放并免除掏耳朵有解压功效从孩子出生到现在就没有掏过耳屎,因为孩子小总是动来动去怕碰到专家说孩子的耳朵最好别掏,因为通过运动和吃饭咀嚼,耳屎会自然脱落的我看头条有个小朋友耳屎都变成黑石头了疼的得了中耳炎去了中国东航均瑶集团及其一致行动人持股比例降至8。9中国东航11月13日公告,11月9日,公司完成非公开发行2,494,930,875股A股,公司总股本从16,379,509,203股增加至18,874,440,078股,股东均瑶集欧洲武林豪杰齐聚希腊,中华武术闪耀文明古国当地时间11月11日晚,以中国传统武术为核心的第十八届欧洲武术锦标赛暨第六届欧洲传统功夫比赛开幕式在希腊海滨城市卢特拉基市(Loutraki)体育馆隆重举行。来自20个国家近700湿气,是真实存在的吗?成年人emo瞬间当你对他说,最近有点累而他却回你湿气重我是不是湿气重?怎样除湿气?不夸张地说几乎没有哪个华夏儿女没听过湿气重然而医学上似乎没有这个概念湿气重仿佛是一种只有中国人才能讲真,关于吃主食这件事儿,你可能真的不太懂!俗话说民以食为天可见饮食对人们的重要性一日三餐在生活的构成中占据了很大的比重即使这样有一些关于吃饭的问题很多人还不是很懂所以今天一起来了解每顿饭必吃的主食看看主食到底吃多少?怎么吃关于冬天养生今天的三个月里,天地万物都在封闭潜藏。大地冰冻,这时尽量不要扰动阳气,根据各个人情况,尽量做到早睡晚起,早晚的大致要求为早即太阳山后,寒气明显的时候(九点左右即可),晚即早上太阳升阳虚又阴虚?给你介绍6种中成药,让你补阳同时又补阴阳虚是指体内阳气不足,然后温煦推动的力量减退,从而出现一些虚寒类的症候,常见有怕冷小便量多或者大便泄泻面色恍白,喜欢喝热水,同时会伴有乏力气短等临床表现。阴虚是指体内阴液不足,不能每天学习一个穴位,清热的名穴阳交阳交能提肾气,对于搭配治疗腰膝酸冷很好!本穴为本经与阳维之会,又本穴挨近足太阳阳明。故针灸大成谓本穴斜属三阳分肉之间,为阳维之郄。犹足三阳与阳维脉四经之交会也,故名阳交。本穴与外丘
白衬衫可不是随便的单品!不按照这个模板来,很难穿出高级感最近听很多人都在讨论白衬衫,她们有的人说,白衬衫方便又好看,随便一搭就能出门,也有的人说白衬衫经典接地气,闭着眼穿都不会出错。但我想说的是,白衬衫真不是这样的,按照常规理论来说,白浅谈1。20版本加强后的T57开语音组两个大哥,它就是暴力收割机各位车长老爷们大家好啊,我是阿纳贝尔丶卡多。就在今天,1。20版本正式在国服更新了,此前我们提到的大量车辆性能修改也已经实装了。在接下来的日子里,我会逐个给大家展示这些坦克的性能变B社宣布游戏完美音浪玩家数量突破200万IT之家3月2日消息,B社(Bethesda)本周三宣布,游戏完美音浪(HiFiRush)玩家数量突破200万。这款游戏于今年1月24日在XboxXboxGamePass和PC平台新手化妆顺序还不会化妆的美女有口福了,这篇文章详细讲解新手化妆顺序。底妆篇UNNY防晒霜四季必备,不搓泥。花园备忘录妆前乳奶霜质地很润,妆前打底底妆很服帖。嘉利玛粉底液妈生好皮肤奶油肌妆感,持你能想象助你约会成功的是一双丝袜吗?大家好欢迎来到汲润丝袜聊天室。好久不见,今天小编和大家一起聊聊丝袜的故事,分享丝袜小知识。大家平时都是怎么选购丝袜的,关于我们是怎样的一个品牌。或许看了下面的文章能有所收获。1。传认知的觉醒1来自教育,剩下的99全部来自千刀万剐认知模糊,行为就会模糊。巨大的失败,来自巨大的无知。认知的觉醒,1来自教育,剩下的99,全部来自千刀万剐。这个世界99的老板,全部全部站在愚昧之巅。情绪不稳定,抱怨,负能量,心理脆真如俗话所说,怕什么来什么当我坐在书桌前,狠狠地吐出那令人贪婪的烟气时,时间仿佛静止了,心也舒坦了许多,人却惆怅了起来。上班下班是这个时代多数人的常态日常生活秩序。说到上下班,可不得谈谈这期间的规矩。清晨,我是大海的叹息阅满鹤湖浪之歌纪伯伦文李唯中译我与海岸是一对情侣,爱情使我俩接近,风又把我俩分离。我来自碧海丹霞之后,以便让我的银沫与它那金沙结合,用我的唾液把我的心冷却。黎明时分,我对着情人的耳朵山盟海教父作者马里奥佐普经典语录大家同样是人,要一个人央求另一个人办一件事,这可需要多大的勇气。1他懂得社会上常常会有突如其来的侮辱,那是必须忍受的。在这个世界上,常常会出现这样的情况最微不足道的人,如果他时刻留弘一法师遇见,是因为有债要还了,离开,是因为还清了弘一法师曾开示后人遇见,是因为有债有还,离开,是因为还清了。前世不欠,今生不见。缘起,我在人群中看见你,缘散,我看见你在人群中。如若流年有爱,就心随花开,如若人走茶凉,便守心自暖。感恩与美在快节奏的生活中,我们很容易失去对生活的感恩之心。然而,当我们放慢脚步审视周围的一切时,会发现我们身边充满了美丽的事物和人,这时,我们也应该开始对它们感恩。首先,我们应该感恩周围的