纠纷奇闻社交美文家庭
投稿投诉
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

Qt绘制系统

12月16日 凉夕夏投稿
  Qt绘制系统简介
  Qt的绘图系统允许使用相同的API在屏幕和其它打印设备上进行绘制。整个绘图系统基于QPainter,QPainterDevice和QPaintEngine三个类。QPainter用来执行绘制的操作;QPaintDevice是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间;QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。QPaintEngine类应用于QPainter和QPaintDevice之间,通常对开发人员是透明的。除非你需要自定义一个设备,否则你是不需要关心QPaintEngine这个类的。
  我们可以把QPainter理解成画笔;把QPaintDevice理解成使用画笔的地方,比如纸张、屏幕等;而对于纸张、屏幕而言,肯定要使用不同的画笔绘制,为了统一使用一种画笔,我们设计了QPaintEngine类,这个类让不同的纸张、屏幕都能使用一种画笔。程序
  main。cppincludeQApplicationincludepaint。hintmain(intargc,charargv){QApplicationa(argc,argv);PaintedWmywindow。show();returna。exec();}
  paint。hincludeQWidgetincludeQPainterclassPaintedWidget:publicQWidget{QOBJECTpublic:PaintedWidget(QWidgetparent0);protected:voidpaintEvent(QPaintEvent);};
  paint。cppincludepaint。hPaintedWidget::PaintedWidget(QWidgetparent):QWidget(parent){resize(400,400);setWindowTitle(tr(PaintDemo));}voidPaintedWidget::paintEvent(QPaintEvent){QPainterpainter(this);QPenpen(Qt::green,3,Qt::DashDotLine,Qt::RoundCap,Qt::RoundJoin);painter。setPen(pen);painter。drawLine(80,100,300,300);painter。setPen(Qt::red);painter。drawRect(10,10,100,300);painter。setPen(QPen(Qt::green,5));painter。setBrush(Qt::blue);painter。drawEllipse(50,150,200,100);}
  在构造函数中,我们仅仅设置了窗口的大小和标题。
  paintEvent()函数则是绘制的代码。首先,我们在栈上创建了一个QPainter对象,也就是说,每次运行paintEvent()函数的时候,都会重建这个QPainter对象。QPainter接收一个QPaintDevice指针作为参数。QPaintDevice有很多子类,比如QImage,以及QWidget。QPaintDevice可以理解成要在哪里去绘制,而现在我们希望画在这个组件,因此传入的是this指针。
  注意,这一点可能会引发某些细节问题:由于我们每次重建QPainter,因此第一次运行时所设置的画笔颜色、状态等,第二次再进入这个函数时就会全部丢失。有时候我们希望保存画笔状态,就必须自己保存数据,否则的话则需要将QPainter作为类的成员变量。paintEvent()作为重绘函数,会在需要重绘时由Qt自动调用。需要重绘可能发生在很多地方,比如组件刚刚创建出来的时候就需要重绘;组件最大化、最小化的时候也需要重新绘制;组件由遮挡变成完全显示的时候也需要等等。程序运行结果
  画刷和画笔
  Qt绘图系统定义了两个绘制时使用的关键属性:画刷和画笔。前者使用QBrush描述,大多用于填充;后者使用QPen描述,大多用于绘制轮廓线。画刷画刷的style()定义了填充的样式,使用Qt::BrushStyle枚举,默认值是Qt::NoBrush,也就是不进行任何填充。我们可以从下面的图示中看到各种填充样式的区别:画刷的color()定义了填充模式的颜色。这个颜色可以是Qt预定义的颜色常量,也就是Qt::GlobalColor,也可以是任意QColor对象。画刷的gradient()定义了渐变填充。这个属性只有在样式是Qt::LinearGradientPattern、Qt::RadialGradientPattern或者Qt::ConicalGradientPattern之一时才有效。渐变可以由QGradient对象表示。Qt提供了三种渐变:QLinearGradient、QConicalGradient和QRadialGradient,它们都是QGradient的子类。我们可以使用如下代码片段来定义一个渐变的画刷:QPainterpainter(this);QLinearGradientlinearGradient(200,50,300,50);linearGradient。setColorAt(0,Qt::red);linearGradient。setColorAt(1,Qt::green);painter。setBrush(linearGradient);painter。drawEllipse(QPointF(250,50),50,50);QRadialGradientradialGradient(QPointF(50,50),50,QPointF(50,50));radialGradient。setColorAt(0,QColor(255,255,100,150));radialGradient。setColorAt(1,QColor(0,0,0,50));painter。setBrush(radialGradient);painter。drawEllipse(QPointF(50,50),50,50);QConicalGradientconicalGradient(QPointF(150,50),60);conicalGradient。setColorAt(0。2,Qt::white);conicalGradient。setColorAt(0。9,Qt::black);painter。setBrush(conicalGradient);painter。drawEllipse(QPointF(150,50),50,50);
  运行结果如下:
  画刷样式是Qt::TexturePattern时,texture()定义了用于填充的纹理。注意,即使你没有设置样式为Qt::TexturePattern,当你调用setTexture()函数时,QBrush会自动将style()设置为Qt::TexturePattern。QPainterpainter(this);QBbrush。setTexture(QPixmap(image。jpg));painter。setBrush(brush);painter。drawEllipse(50,100,300,200);
  运行结果:
  画笔
  QPen定义了用于QPainter应该怎样画线或者轮廓线。
  画笔具有样式、宽度、画刷、笔帽样式和连接样式等属性。1。画笔的样式style()定义了线的样式。画刷brush()用于填充画笔所绘制的线条。2。笔帽样式capStyle()定义了使用QPainter绘制的线的末端;3。连接样式joinStyle()则定义了两条线如何连接起来。4。画笔宽度width()或widthF()定义了画笔的宽。注意,不存在宽度为0的线。
  注:假设你设置width为0,QPainter依然会绘制出一条线,而这个线的宽度为1像素。也就是说,画笔宽度通常至少是1像素。
  这么多参数既可以在构造时指定,也可以使用set函数指定,完全取决于你的习惯,例如:QPainterpainter(this);QPenpen(Qt::green,3,Qt::DashDotLine,Qt::RoundCap,Qt::RoundJoin);painter。setPen(pen);
  等价于QPainterpainter(this);QPcreatesadefaultpenpen。setStyle(Qt::DashDotLine);pen。setWidth(3);pen。setBrush(Qt::green);pen。setCapStyle(Qt::RoundCap);pen。setJoinStyle(Qt::RoundJoin);painter。setPen(pen);
  使用构造函数的优点是代码较短,但是参数含义不明确;使用set函数则正好反过来。
  默认的画笔属性是纯黑色,0像素,方形笔帽(Qt::SquareCap),斜面型连接(Qt::BevelJoin)。1。下面是画笔样式的示例:
  你也可以使用setDashPattern()函数自定义样式,例如如下代码片段:QPQVqrealspace4;dashes1space3space9space27space9pen。setDashPattern(dashes);2。笔帽定义了画笔末端的样式,例如:
  他们之间的区别是,Qt::SquareCap是一种包含了最后一个点的方形端点,使用半个线宽覆盖;Qt::FlatCap不包含最后一个点;Qt::RoundCap是包含最后一个点的圆形端点。具体可以参考下面的示例(出自《CGUIProgrammingwithQt4,2ndEdition》):
  3。连接样式定义了两条线连接时的样式,例如:
  同样,可以参考下面图示来理解这几种连接样式的细节(出自《CGUIProgrammingwithQt4,2ndEdition》):
  反走样
  我们在光栅图形显示器上绘制非水平、非垂直的直线或多边形边界时,或多或少会呈现锯齿状外观。这是因为直线和多边形的边界是连续的,而光栅则是由离散的点组成。在光栅显示设备上表现直线、多边形等,必须在离散位置采样。由于采样不充分重建后造成的信息失真,就叫走样;用于减少或消除这种效果的技术,就称为反走样。
  反走样是图形学中的重要概念,用以防止通常所说的锯齿现象的出现。很多系统的绘图API里面都内置了有关反走样的算法,不过由于性能问题,默认一般是关闭的,Qt也不例外。下面我们来看看代码:voidpaintEvent(QPaintEvent){QPainterpainter(this);painter。setPen(QPen(Qt::black,5,Qt::DashDotLine,Qt::RoundCap));painter。setBrush(Qt::yellow);painter。drawEllipse(100,50,200,150);painter。setRenderHint(QPainter::Antialiasing,true);painter。setPen(QPen(Qt::black,5,Qt::DashDotLine,Qt::RoundCap));painter。setBrush(Qt::yellow);painter。drawEllipse(100,220,200,150);}
  显然,我们通过这条语句,将Antialiasing属性(也就是反走样)设置为true。经过这句设置,我们就打开了QPainter的反走样功能。还记得我们曾经说过,QPainter是一个状态机,因此,只要这里我们打开了它,之后所有的代码都会是反走样绘制的了。
  点击领取Qt学习资料视频教程链接
  坐标变换
  前面说过,QPainter是一个状态机。那么,有时我想保存下当前的状态:当我临时绘制某些图像时,就可能想这么做。当然,我们有最原始的办法:将可能改变的状态,比如画笔颜色、粗细等,在临时绘制结束之后再全部恢复。对此,QPainter提供了内置的函数:save()和restore()。save()就是保存下当前状态;restore()则恢复上一次保存的结果。这两个函数必须成对出现:QPainter使用栈来保存数据,每一次save(),将当前状态压入栈顶,restore()则弹出栈顶进行恢复。
  在了解了这两个函数之后,我们就可以进行示例代码了:voidPaintDemo::paintEvent(QPaintEvent){QPainterpainter(this);painter。fillRect(10,10,50,100,Qt::red);painter。save();painter。translate(100,0);向右平移100pxpainter。fillRect(10,10,50,100,Qt::yellow);painter。restore();painter。save();painter。translate(300,0);向右平移300pxpainter。rotate(30);顺时针旋转30度painter。fillRect(10,10,50,100,Qt::green);painter。restore();painter。save();painter。translate(0,100);向下平移100pxpainter。scale(2,2);横坐标单位放大2倍,纵坐标放大2倍painter。fillRect(10,10,50,100,Qt::blue);painter。restore();painter。save();painter。translate(200,100);向右平移200px向下平移100pxpainter。shear(0,1);横向不变,纵向扭曲1倍painter。fillRect(10,10,50,100,Qt::cyan);painter。restore();}
  Qt提供了四种坐标变换:平移translate,旋转rotate,缩放scale和扭曲shear。在这段代码中,我们首先在(10,10)点绘制一个红色的50100矩形。保存当前状态,将坐标系平移到(100,0),绘制一个黄色的矩形。注意,translate()操作平移的是坐标系,不是矩形。因此,我们还是在(10,10)点绘制一个50100矩形,现在,它跑到了右侧的位置。然后恢复先前状态,也就是把坐标系重新设为默认坐标系(相当于进行translate(100,0)),再进行下面的操作。之后也是类似的。由于我们只是保存了默认坐标系的状态,因此我们之后的translate()横坐标值必须增加,否则就会覆盖掉前面的图形。所有这些操作都是针对坐标系的,因此在绘制时,我们提供的矩形的坐标参数都是不变的。
  运行结果如下:
  窗口坐标voidPaintDemo::paintEvent(QPaintEvent){QPainterpainter(this);painter。setWindow(0,0,200,200);painter。fillRect(0,0,200,200,Qt::red);}
  运行结果:
  原本窗口大小为400400,但这里利用setWindow重新分配了窗口坐标为200200,即便拖动窗口大小红色矩形也会覆盖整个窗口,由于setWindow将窗口的左上角固定位(0,0)窗口的右下角固定为(200,200)。此时再画矩形就是在这个窗口坐标下画。视口坐标QPainterpainter(this);painter。setWindow(0,0,200,200);painter。setViewport(100,100,100,100);painter。fillRect(0,0,200,200,Qt::red);
  利用setVieweport将窗口映射到视口。
投诉 评论

被窝里的快乐冬日生活打卡季冬天到了大家都有赖床的习惯吧,主要是外面太冷了,不想起床,离开温暖的被窝,一天躺着也不是个事啊,打游戏成为了我们的必备选择,手机端游戏很多,但绝大多数人都会……夏日游乐场活动第四季规则又更改了夏日游乐场活动第四季规则再次更改了,和以往不同的是,这次更改的是在周二凌晨就更改了,具体的更改时间不太清楚,仅仅一天,就改规则了,让人措手不及。还好我周一已经到了第五关,……黑色丝袜搭配长靴,初冬的穿搭风格,依旧可以展示身材头条创作挑战赛到了初冬季节,不少人还是想要搭配出不一样的感觉,生活也要精彩一些,这样的生活也会变得更加精彩一些,黑色丝袜搭配长靴,保暖还可以秀一下身材的穿搭,也是很多精致……头发可以一直长,为什么隐私处的毛不能一直生长?我们都知道,人类是由古猿进化而来的,你要是硬说自己是猴子进化来的的也不是不可以。从满身是毛的猴子进化到现在的人类,现在只有几处还保留着长毛毛特性,分别有头部的头发,私处的y毛,……美女的疯狂,一组老照片看看上个世纪欧美流行的画丝袜丝袜最早诞生在15世纪,距今已经600年了。当时裤袜生产还依赖手工和天然材料。欧洲上流社会对裤袜非常迷恋,不乏彩色裤袜,可谓是大热时尚单品。16世纪初,西班牙人开始把连裤……打败模拟城市后,P社再次对EA出手,新作狙击模拟人生EA旗下原本有两大知名模拟游戏系列,第一个是模拟整体城市发展玩法的《模拟城市》,第二个则是模拟个体个人发展的《模拟人生》。这两个系列原本都在自己的赛道上一同天下,然而自从……大陆房企债务重组谈判停滞,曾牛鬼蛇神的地王拖累房地产行业复苏中国开发商就300多亿美元违约债务与境外债券投资者进行的谈判进展寥寥,在中国房地产业尝试恢复健康之际,给该行业平添不确定性。去年中国房地产行业急剧放缓之际,数十家中国开发……Qt绘制系统Qt绘制系统简介Qt的绘图系统允许使用相同的API在屏幕和其它打印设备上进行绘制。整个绘图系统基于QPainter,QPainterDevice和QPaintEngine……十一假期本地游唱主角市民热衷拆分长假微度假黄金周进入倒计时。北京青年报记者从携程、马蜂窝、飞猪、同程、途牛、去哪儿、途家、木鸟民宿等多家旅游平台了解到,近期关于十一去哪儿玩的搜索热度大涨。在疫情等不确定因素的影响下,本……中国股市猴痘病毒站上风口,重点关注这五只龙头建议收藏猴痘病毒概念:近日,国外多国报告新增猴痘确诊或疑似病例,美欧正在对此开展调查,并订购疫苗用以预防。猴痘病毒防治概念股午后再度拉升,华仁药业(300110)、亚太药业……续航基本腰斩!懂车帝发布40款电动车续航冬测成绩对于广大消费者而言,新能源车续航焦虑似乎是永远绕不开的话题,不少车企在宣传新车时也会刻意强调续航里程,将其作为产品的一大卖点,但是众所周知车企宣传的NEDC综合续航里程是一个相……特斯拉的新车型攻击明年将成为特斯拉历史上最大的一年,随着一系列新产品的推出,以及对Model3和ModelY的更新,有可能将ElonMusk的电动汽车公司推向更高的高度。一系列长期承诺似乎……
各国父亲节习俗父亲节的由来,解密你不了解的父亲节高考696分小哥哥说就是想当兵小哥哥一句话秒变刘昊然高考生因系统崩溃错过志愿填报事件始末详情曝光网友争议不断的哥听到女儿高考成绩后激动落泪下一秒的一句话让人泪目三胞胎姐妹高考均过610分学霸自爆学习方法比白色包容,比棕色独立,米色赢在哪?凭什么优雅又讲究?欧空局火星探测器4年内可能都无法发射,俄罗斯我们将独立完成宝宝太潮了高考别涂好看的指甲油高考可以涂指甲油吗(图)眼综合眼窝凹陷上睑下垂三眼皮难做的眼部整形案例高考遇紧急情况咋整高考遇突发状况,教你高考应急从理论到搭建,了解B端色彩系统绝味食品到底是鸭脖卤味之王还是投资帝国?女性痛经期间可以使用的缓解痛经小妙招灰色许愿树(三)常吃避孕药的危害有哪些?怀孕为什么便秘(自从怀孕就便秘是怎么回事)国内一款逆天安卓UI随意更改GPS定位,通话背景音都能伪造车厘子在零下度保存会怎样一封情书作文500字3篇学瑜伽教练的最佳年龄学瑜伽的最佳年龄大众出行拟增资扩股引入投资人阿里巴巴,共计4000万元假如我会克隆的想象作文350字招打造高质量演讲大佬必杀绝技

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形