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

第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); }
  现在运行程序,效果如下图所示。
  结语
  本节讲到的涂鸦板,只是为了实践前面的知识,起到抛砖引玉的作用。大家可以根据自己的理解继续探究下去。在下一节,我们将讲解怎样在涂鸦板上绘制出矩形、椭圆等图形。

第一次鸦片战争(六)中国作为正义的一方却开启了近百年的屈辱史(三)军力羸弱,装备落后接续上文三是以军队编制而言,道光朝的清军虽有八十万之众,但主体的京师八旗驻防八旗乃世袭身份,生而食粮,传数代之后,大部分人已忘练武习操,日渐颓废,而绿营官兵英伟达RTX4080在英国跌至1099英镑,比原价低100英镑本文转自IT之家作者问舟随着AMD7900XTX的到来,英伟达GeForceRTX4080的处境似乎有点尴尬,甚至此前一度传出消息称RTX4080要降价。考虑到RTX4080无法像商业空间元宇宙是什么模样?商汤签约300家商业综合体赋能新零售图说在各地商业综合体打造的高人气元宇宙应用采访对象供图(下同)新民晚报讯(记者郜阳)在AIXR技术的创新驱动下,以购物中心为代表的现代商业综合体在构建商业空间元宇宙过程中,正在重新给宇宙拍了部延时电影太空望远镜拍到的蜘蛛星云的恒星形成区域拼接图片图片来源NASA浩源利用NASA的NEOWISE太空望远镜拍摄的大量全天空地图,天文学家们剪辑出了一部延时的天空大电影,以影像的形式揭美女演员陈红28岁晚婚嫁导演陈凯歌,生两孩,54岁还美如少女1968年12月13日,陈红出生在江西省上饶市的一个军人干部家庭。父母是军队干部。陈红小时候就长得漂亮乖巧,像是一个可爱的洋娃娃。父母从小就对女儿,各方面都要求严格。还教育她不要以为什么说香港繁荣的基础是广东?如果要找出中国最互补的两个省份,非广东和香港莫属香港面积非常有限,需要广东这样的经济腹地由于两省的制度不一样,香港是资本主义社会因此广东需要香港这样的对外窗口深圳主打金融科创,广州2022财年亏损18。16亿,靠港府续命的香港海洋公园能走多远?记者张熹珑编辑等来了政府的救场,却没等来游客。12月7日,香港海洋公园交出史上最差成绩单。根据其20212022财年业绩报告,2021年7月1日2022年6月30日,海洋公园年度亏台湾歌手黄安定居大陆!过60岁生日与异性接吻,面色红润状态好近日,台湾知名歌手黄安在社交平台上发文晒照,为自己庆祝60岁生日,并配文称12月8日是我60岁生日,发表一点架子感言吧!看来过生日让他的心情也是变得十分不错。而从他写的长文中得知,2022流量重度使用者必看这几款100GB流量卡给你解决方案官方的流量卡了,有正规的11位数号码,能登录营业厅查流量话费,售后是人工客服,但是这类优惠的流量卡一般是各地级市推出的优惠,有一定的数量或者时间限制,所以上下架特别快,咱们看到合适有我的女孩儿在侧,阳光就是我们今生的道路海上生明月,天涯共此时。这简单的诗句倾诉不了我对你的情愫,清潭一般的眸子看穿了我的炽热的爱情原野,执子之手与子偕老,这不是今生的奢侈花前月下,有多少从心底涌现的情爱情不自已!拥着你成都女孩硅谷升职记36岁当上硅谷大厂CFO为什么是她?眼下,硅谷的日子不太好过,大公司都在经历痛苦的裁员紧缩潮。先是马斯克接管推特后裁员50,接着扎克伯格也宣布裁员13,涉及上万人。在这个人心惶惶的
如何根据孕期反应推断宝宝性别?如何根据孕期反应推断宝宝性别?很多老年人会通过女性怀孕后的一些行为和身体特征来判断怀的是男孩还是女孩,这些判断有什么依据吗?根据孕期反应,真的能判断出孩子的性别吗?其实孕期反应和宝宝宝几个月后,才可以不用拍嗝了?十月怀胎时准妈妈是紧张又忐忑不安的,可一朝分娩之后在漫长的育儿路上尤其是婴儿时期可以宝妈是焦虑的,如果你是新手妈妈这种焦虑不安的感觉会相当的强烈。作为宝妈们宝宝一般是几个月以后就不8988元起售!华为P60Art值得入手吗?众所周知,华为P60系列旗舰手机已经在3月23日正式发布,共包括P60P60ProP60Art三款新机,其中P60Art定义为顶配机型,拥有着独特的外观设计以及独有的1TB存储规格十大轻量级linux系统?以下是十大轻量级Linux系统Lubuntu基于Ubuntu,使用LXQt桌面环境,非常轻量级。PuppyLinux非常小巧的Linux发行版,可以在旧电脑上运行,它的ISO文件大外媒爆料微软新Windows系统将提高门槛,老设备恐淘汰百能云芯微软有意把Windows系统的开发周期与升级节奏步调,改为每三年推出重磅升级的大型版本。继先前传出微软已着手展开下一代作业系统的开发部署,最快有望于明年2024年底前登场。WindCCSInsight预测今年全球手机出货量将跌至10多年来的最低点据TelecomTV3月27日报道,研究机构CCSInsight的最新预测显示,今年全球手机出货量将跌至10多年来的最低点,然而,尽管面临全球经济压力,新型5G手机的销售预计仍将保初次佩戴爱唯听助听器,如何缓解不适对于初次佩戴爱唯听助听器的人来说,可能会有一些不适应感。这些不适应感可能包括听力变化佩戴的压力或不适对新的声音环境的适应等。但是,一旦适应了助听器,它们会大大提高听力和生活质量。以做windows界面,用QT还是MFC?使用Qt吧,前提是在这两者下进行选择。既然提到了Qt和MFC,我想题主肯定是一个C的开发者。其实,在我看来,Windows下开发界面程序,还有很多其他的选择。下面我就连同QtMFC麒麟990集成5g和麒麟990外挂巴龙5000差距大吗?麒麟990集成5G和麒麟990外挂巴龙5000差距大吗?那下面我给大家说一下这两款芯片有什么区别,在做一下对比。1。麒麟9905G搭载这款处理器的手机,目前有华为Mate30Pro一般排卵日在月经的什么时候?最简单的方法是怎么计算的?感谢邀请,我是京妈说,很高兴回答您的问题。对于孕育期的女性来说,想要成功怀上宝宝,找准排卵日是最重要的一个环节。通常初次怀孕的女性对排卵日并不是很敏感,她们怀孕大多是顺其自然,只有糖尿病吃大蒜能降血糖吗?如何吃才有效果?感谢邀请。糖尿病患者吃大蒜不能直接起到降糖的效果,大蒜中或有一些活性物质有助于血糖的控制,但光靠吃大蒜并不能稳定血糖,即使吃了算,糖友还是应当保证降糖药的摄入,胰岛素注射量也不要减