C++ GUI Qt4学习笔记08
- 本章介绍Qt的二维图形引擎,Qt的二维图形引擎是基于QPainter类的。<span style="color:#ff0000;">QPainter既可以绘制几何图形(点、线、矩形等),也可以绘制像素映射、图像和文字。此外QPainter还支持一些高级特性,例如反走样、像素混合、渐变填充和矢量路径等。QPainter也支持线性变换,例如平移、旋转、错切和缩放。</span>
QPainter可以画在“绘图设备”(QWidget、QPixmap、QImage和QSvgGenerator)上,也可以与QPrinter一起使用来打印文件和创建PDF文档。
重新实现QWidget::PaintEvent()可用于定制窗口部件,随心所欲的控制他们的外观
一项普通的需求是在二维画板上显示大量的、轻量级的、可以用户交互的、任意形状的项。
可使用OpenGL命令来代替QPainter。OPenGL是一个绘制三维图形的标准库。
8.1用QPainter绘图
想要在绘图设备上绘图,只需要创建一个QPainter,在将指针传到该设备中。
使用QPainter的draw...()函数,可以绘制各种各样的形状。绘制的效果取决于QPainter的设置。三个主要的设置是画笔、画刷、字体:
①画笔用来画线和边缘。QPen,设置属性setPen()
②画刷用来填充几何形状的图案。QBrush,设置属性setBrush()
③字体用来绘制文字。QFont,设置属性setFont()
绘制椭圆:
- <span style="color:#33cc00;BACKGROUND-COLOR: #ffffff">QPainter painter(this);
- painter.setRenderHint(QPainter::Antialiasing,true);
- painter.setPen(QPen(Qt::black,12,Qt::DashDotLine,Qt::RoundCap));
- painter.setBrush(QBrush(Qt::green,Qt::SolidPattern));
- painter.drawEllipse(80,80,400,240);</span>
setRenderHint(QPainter::Antialiasing,true)可以启用反走样,可在支持这一特性的平台和设备上得到平滑的边缘。
QPainterPath类可以通过连接基本的图形元素来确定任意的矢量图形:直线、椭圆、多边形等绘制路径。绘制路劲是基本的图元,任何图形或图形组合都可以用绘制路径描述。路径可以确定一个边缘,由边缘锁定的区域可以用画刷来填充。
在现代应用中,渐变填充已成为单色填充的流行替代品。渐变填充利用颜色差值使得两个或更多颜色之间能够平滑的过度。
Qt支持3种类型的渐变:
线性渐变,由两个控制点定义,连接这两点的线上有一系列的颜色断点。
锥形渐变,由一个中心点和一个角度定义。
辐射渐变,由一个中心点、半径、一个焦点,以及颜色断点定义。颜色由焦点向外扩散,焦点可以是中心点或者圆内的其他点。
QPainter还有其他影响图形和文字绘制方式的设置这里不详细介绍了。
8.2坐标系统变换
在QPainter的默认坐标系中,点(0,0)位于绘图设备的左上角,x坐标向右增长,y坐标向下增长。默认坐标系的每个像素占1x1大小的区域。
理论上像素的中心取决于半像素坐标,一个像素正好位于四个像素的重合处。如果不需要这种效果,可以通过制定半像素坐标或者通过便宜QPainter(+0.5,+0.5)来避免这种效果的出现。
QPainter的视口,是物理坐标系下制定的任意矩形。
QPainter的窗口也是指同一矩形,只不过是在逻辑坐标系下。这种窗口-视口机制对于编写独立于绘制设备大小和分辨率的绘制代码是有用的。
世界变换是在窗口-视口转换之外使用的变换矩阵。它允许移动、缩放、旋转或者拉伸绘制的项。
OvenTimer窗口部件代码
这个OvenTimer模仿烤箱的定时器,它是烤箱内置的钟表。用户可以单击刻度来设置持续时间。转轮会自动的逆时针转到0,OvenTimer在这一点发射timeout()信号。
ovenTimer.h
- #ifndef OVENTIMER_H
- #define OVENTIMER_H
- #include <QDateTime>
- #include <QWidget>
- class QTimer;
- class OvenTimer : public QWidget
- {
- Q_OBJECT
- public:
- OvenTimer(QWidget *parent = 0);
- void setDuration(int secs);
- int duration() const;
- void draw(QPainter *painter);
- signals:
- void timeout();
- protected:
- void paintEvent(QPaintEvent *event);
- void mousePressEvent(QMouseEvent *event);
- private:
- QDateTime finishTime;
- QTimer *updateTimer;
- QTimer *finishTimer;
- };
- #endif
oventimer.cpp
- #include <QtGui>
- #include <cmath>
- #ifndef M_PI
- #define M_PI 3.14159265359
- #endif
- #include "oventimer.h"
- const double DegreesPerMinute = 7.0;
- const double DegreesPerSecond = DegreesPerMinute / 60;
- const int MaxMinutes = 45;
- const int MaxSeconds = MaxMinutes * 60;
- const int UpdateInterval = 5;
- OvenTimer::OvenTimer(QWidget *parent)
- : QWidget(parent)
- {
- finishTime = QDateTime::currentDateTime(); //获取当前时间
- updateTimer = new QTimer(this);
- connect(updateTimer, SIGNAL(timeout()), this, SLOT(update()));
- finishTimer = new QTimer(this);
- finishTimer->setSingleShot(true);
- connect(finishTimer, SIGNAL(timeout()), this, SIGNAL(timeout()));
- connect(finishTimer, SIGNAL(timeout()), updateTimer, SLOT(stop()));
- QFont font;
- font.setPointSize(8); //设置窗口字体的大小
- setFont(font);
- }
- void OvenTimer::setDuration(int secs) //设置了烤箱定时器的持续时间为给定的秒数。
- {
- secs = qBound(0, secs, MaxSeconds); //防止越界0~MaxSeconds
- finishTime = QDateTime::currentDateTime().addSecs(secs);
- if (secs > 0) {
- updateTimer->start(UpdateInterval * 1000);
- finishTimer->start(secs * 1000);
- } else {
- updateTimer->stop();
- finishTimer->stop();
- }
- update();
- }
- int OvenTimer::duration() const //获取定时器完成前剩余的秒数。
- {
- int secs = QDateTime::currentDateTime().secsTo(finishTime);
- if (secs < 0)
- secs = 0;
- return secs;
- }
- void OvenTimer::mousePressEvent(QMouseEvent *event)
- {
- QPointF point = event->pos() - rect().center();
- double theta = std::atan2(-point.x(), -point.y()) * 180.0 / M_PI;
- setDuration(duration() + int(theta / DegreesPerSecond));
- update();
- }
- void OvenTimer::paintEvent(QPaintEvent * /* event */)
- {
- QPainter painter(this);
- painter.setRenderHint(QPainter::Antialiasing, true);
- int side = qMin(width(), height()); //返回两个参数中较小的一个
- painter.setViewport((width() - side) / 2, (height() - side) / 2,
- side, side);
- painter.setWindow(-50, -50, 100, 100);
- draw(&painter);
- }
- void OvenTimer::draw(QPainter *painter)
- {
- static const int triangle[3][2] = {
- { -2, -49 }, { +2, -49 }, { 0, -47 }
- };
- QPen thickPen(palette().foreground(), 1.5); //palette().foreground()得到笔刷
- QPen thinPen(palette().foreground(), 0.5);
- QColor niceBlue(150, 150, 200);
- painter->setPen(thinPen);
- painter->setBrush(palette().foreground());
- painter->drawPolygon(QPolygon(3, &triangle[0][0]));
- QConicalGradient coneGradient(0, 0, -90.0);
- coneGradient.setColorAt(0.0, Qt::darkGray);
- coneGradient.setColorAt(0.2, niceBlue);
- coneGradient.setColorAt(0.5, Qt::white);
- coneGradient.setColorAt(1.0, Qt::darkGray);
- painter->setBrush(coneGradient);
- painter->drawEllipse(-46, -46, 92, 92);
- QRadialGradient haloGradient(0, 0, 20, 0, 0);
- haloGradient.setColorAt(0.0, Qt::lightGray);
- haloGradient.setColorAt(0.8, Qt::darkGray);
- haloGradient.setColorAt(0.9, Qt::white);
- haloGradient.setColorAt(1.0, Qt::black);
- painter->setPen(Qt::NoPen);
- painter->setBrush(haloGradient);
- painter->drawEllipse(-20, -20, 40, 40);
- QLinearGradient knobGradient(-7, -25, 7, -25);
- knobGradient.setColorAt(0.0, Qt::black);
- knobGradient.setColorAt(0.2, niceBlue);
- knobGradient.setColorAt(0.3, Qt::lightGray);
- knobGradient.setColorAt(0.8, Qt::white);
- knobGradient.setColorAt(1.0, Qt::black);
- painter->rotate(duration() * DegreesPerSecond);
- painter->setBrush(knobGradient);
- painter->setPen(thinPen);
- painter->drawRoundRect(-7, -25, 14, 50, 99, 49);
- for (int i = 0; i <= MaxMinutes; ++i) {
- if (i % 5 == 0) {
- painter->setPen(thickPen);
- painter->drawLine(0, -41, 0, -44);
- painter->drawText(-15, -41, 30, 30,
- Qt::AlignHCenter | Qt::AlignTop,
- QString::number(i));
- } else {
- painter->setPen(thinPen);
- painter->drawLine(0, -42, 0, -44);
- }
- painter->rotate(-DegreesPerMinute);
- }
- }
8.3用QImage高质量绘图
绘图时,我们可能需要面对速度和准确率的折中问题
C++ GUI Qt4学习笔记08的更多相关文章
- C++ GUI Qt4学习笔记01
C++ GUI Qt4学习笔记01 qtc++signalmakefile文档平台 这一章介绍了如何把基本的C++只是与Qt所提供的功能组合起来创建一些简单的图形用户界面应用程序. 引入两个重要概 ...
- C++ GUI Qt4学习笔记03
C++ GUI Qt4学习笔记03 qtc++spreadsheet文档工具resources 本章介绍创建Spreadsheet应用程序的主窗口 1.子类化QMainWindow 通过子类化QM ...
- C++ GUI Qt4学习笔记09
C++ GUI Qt4学习笔记09 qtc++ 本章介绍Qt中的拖放 拖放是一个应用程序内或者多个应用程序之间传递信息的一种直观的现代操作方式.除了剪贴板提供支持外,通常它还提供数据移动和复制的功 ...
- C++ GUI Qt4学习笔记05
C++ GUI Qt4学习笔记05 qtc++正则表达式 QIntValidator -- 只让用户输入整数 QDoubleValidator -- 只让用户输入浮 ...
- C++ GUI Qt4学习笔记07
C++ GUI Qt4 qtc++scrollobject编程 事件(event)是由串口系统或者Qt自身产生的,用以响应所发生的各类事情.当用户按下或者松开键盘或者鼠标上的按键时,就可以产生一个 ...
- 【QT】C++ GUI Qt4 学习笔记1
Find对话框实现 平台 Qt5.3.2 MinGW4.8.2 注意创建时用QDialog finddialog.h #ifndef FINDDIALOG_H #define FINDDIALOG_H ...
- 【QT】C++ GUI Qt4 学习笔记2
Go To Cell 利用QT Desinger做好界面后加入的代码有 gotocelldialog.h #ifndef GOTOCELLDIALOG_H #define GOTOCELLDIALOG ...
- 【QT】C++ GUI Qt4 学习笔记3
菜单界面的实现. 看书上第三章,好长,好多代码.我敲了半天,想看看效果,结果却显示不出来.仔细一看,发现spreadsheet的实现在第四章.郁闷.... 又到官网上下代码,结果居然不能运行.难道是因 ...
- 【QT】C++ GUI Qt4 学习笔记4
感觉这本书的顺序设计的太不合理了,出现的最多的一句话就是后面会讲.按照使用的顺序讲不行吗?搞得代码都运行不了. 我决定先直接跳到73页,子类化QTableWidgetItem这一节.因为前面功能的实现 ...
随机推荐
- delphi 每英寸相素点取值偏差
在所有资料中,每英寸相素点之比一般是这两个值,即:0.0393700788 25.399999961392 但是在GDI编程中,却遇到LOGPIXELSX LOGPIXELSY 在取值为96DPI ...
- wpf slider刻度
TickFrequency:刻度之间的间隔 IsSnapToTickEnabled:是否对齐到刻度 TickPlacement:刻度位置
- 【计算机视觉】HDR之tone mapping简介
tone Mapping原是摄影学中的一个术语,因为打印相片所能表现的亮度范围不足以表现现实世界中的亮度域,而如果简单的将真实世界的整个亮度域线性压缩到照片所能表现的亮度域内,则会在明暗两端同时丢失很 ...
- Vim文本编辑工具
4文本编辑工具Vim Vim是vi的升级版,编辑文本时vi不会显示颜色而vim会显示颜色. 安装vim工具 #yum install –y vim-enhanced Vim有三种模式:一般模式. ...
- linux 系统目录权限
小结: 目录的读.写.执行权限 1. 可读r:表示具有浏览目录 下面文件及子目录的权限 ls dir 1)如果没有x权限,则不能进到目录,既无法执行cd dir 2)如果没有x权限,ls列表时可以看到 ...
- UrlConnection发送http请求 中文乱码解决
中文乱码 DataOutputStream dos = new DataOutputStream(httpConn.getOutputStream()); //dos.writeBytes(jsonD ...
- [Web 前端] 024 js 的定时器及函数
1. Javascript 定时器 1.1 计时事件 设定一个间隔,时间到了后准时执行代码,此为"计时事件" 1.2 作用 1.制作动画 2.异步操作 1.3 定时器的类型及语法 ...
- Requests的基本使用
Requests库 r=requests.get(url) #返回一个包含服务器资源的Response对象 #构造一个向服务器请求资源的Request对象 格式:requests.get(url,pa ...
- 题解 CF1140D 【Minimum Triangulation】
题意:求将一个n边形分解成(n-2)个三边形花费的最小精力,其中花费的精力是所有三角形的三顶点编号乘积的和(其中编号是按照顶点的顺时针顺序编写的) 考虑1,x,y连了一个三角形,x,y,z连了一个三角 ...
- Java中静态变量和实例变量的区别
静态变量属于类的级别,而实例变量属于对象的级别. 主要区别有两点: 1,存放位置不同 类变量随着类的加载存在于方法区中,实例变量随着对象的对象的建立存在于堆内存中. 2,生命周期不同 类变量的生命周期 ...