#include "widget.h"
///线性渐变(QLinearGradient)
/// 辐射渐变(QRadialGradient)
/// 角度渐变(QConicalGradient)
/// 设置渐变是在QBrush里面
///
///
/// Graphics View 框架包含了一套完整的事件体系,可以用于与场景中的元素
/// 进行双精度的交互。这些元素同样支持键盘事件、鼠标事件等。Graphics View
/// 使用了 BSP 树(Binary Space Partitioning tree,这是一种被广泛应用于
/// 图形学方面的数据结构)来提供非常快速的元素发现,也正因为如此,才能够实现
/// 一种上百万数量级元素的实时显示机制。
/// Graphics View 是一个基于元素(item)的 MV 架构的框架。
/// 它可以分成三个部分:元素 item、场景 scene 和视图 view。
/// 首先创建一个场景(scene),然后创建一个直线对象和一个多边形对象,再使用场景的add()函数,
/// 将直线和多边形添加到场景中,最后通过视图进行观察,就可以看到了
/// MV 架构的意思是,Graphics View 提供一个 model 和一个 view
/// (正如 MVC 架构,只不过 MV 架构少了 C 这么一个组件)。
/// 所谓模型(model)就是我们添加的种种对象;所谓视图(view)
/// 就是我们观察这些对象的视口。同一个模型可以由很多视图从不同的角度进行观察
/// Graphics View 提供了QGraphicsScene作为场景,即是允许我们添加图形的空间,
/// 相当于整个世界;QGraphicsView作为视口,也就是我们的观察窗口,相当于照相机
/// 的取景框,这个取景框可以覆盖整个场景,也可以是场景的一部分;QGraphicsItem
/// 作为图形元件,以便添加到场景中去,Qt 内置了很多图形,比如直线、多边形等,
/// 它们都是继承自QGraphicsItem
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
}
Widget::~Widget()
{
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
///设置反走样
// painter.setRenderHint(QPainter::Antialiasing, true);
// QLinearGradient linear(0,0,200,200);///渐变的起始点和终止点
// linear.setColorAt(0.2, Qt::white);//在 0.2,也就五分之一处设置成白色
// linear.setColorAt(0.6, Qt::green);//在 0.6 也就是五分之三处设置成绿色
// linear.setColorAt(1.0, Qt::black);//1.0 也就是终点处设置成黑色
// painter.setBrush(QBrush(linear));
// painter.drawRect(0,0,300,300);
///色轮
// const int r = 150;
// QConicalGradient conical(r,r,0);//渐变中心设置为(r,r)
// conical.setColorAt(0.0,Qt::red);
// conical.setColorAt(60.0/360.0,Qt::yellow);//将 60 度角设置为黄色。由于一个圆周是 360 度,所以 60.0/360.0 即是这个角度的比例
// conical.setColorAt(120.0/360.0,Qt::green);
// conical.setColorAt(180.0/360.0, Qt::cyan);
// conical.setColorAt(240.0/360.0, Qt::blue);
// conical.setColorAt(300.0/360.0, Qt::magenta);
// conical.setColorAt(1.0, Qt::red);//我们将 1.0 处设置为红色,也就是重新回到起始处
// painter.setPen(Qt::NoPen);//设置nopen不会有外圆的那个圆圈
// painter.setBrush(QBrush(conical));
// painter.drawEllipse(QPoint(r,r),r,r);
///坐标系统
// painter.fillRect(10,10,50,100,Qt::red);
// painter.save();//保存
// painter.translate(100,0);//坐标系向右平移100px
// painter.fillRect(10,10,50,100,Qt::yellow);
// painter.restore();//回到之前状态
// painter.save();//再保存
// painter.translate(200,0);//坐标系向右平移100px
// painter.fillRect(10,10,50,100,Qt::green);
// painter.restore();
// painter.save();
// painter.translate(400, 0); // 向右平移 400px
// painter.scale(2, 3); // 横坐标单位放大 2 倍,纵坐标放大 3 倍
// painter.fillRect(10, 10, 50, 100, Qt::blue);
// painter.restore();
// painter.save();
// painter.translate(600, 0); // 向右平移 600px
// painter.shear(0, 1); // 横向不变,纵向扭曲 1 倍
// painter.fillRect(10, 10, 50, 100, Qt::cyan);
// painter.restore();
///Qt 的坐标分为逻辑坐标和物理坐标。在我们绘制时,
/// 提供给QPainter的都是逻辑坐标。之前我们看到的坐标变换,
/// 也是针对逻辑坐标的。所谓物理坐标,就是绘制底层QPaintDevice的坐标。
/// 单单只有逻辑坐标,我们是不能在设备上进行绘制的。要想在设备上绘制,
/// 必须提供设备认识的物理坐标。Qt 使用 viewport-window 机制将我们提
/// 供的逻辑坐标转换成绘制设备使用的物理坐标,方法是,在逻辑坐标和物理坐
/// 标之间提供一层“窗口”坐标。视口是由任意矩形指定的物理坐标;
/// 窗口则是该矩形的逻辑坐标表示。默认情况下,物理坐标和逻辑坐标是一致的,
/// 都等于设备矩形。
/// 我们将窗口矩形设置为左上角坐标为 (0, 0),长和宽都是 200px。
/// 此时,坐标原点不变,还是左上角,但是,对于原来的 (400, 400) 点,
/// 新的窗口坐标是 (200, 200)。我们可以理解成,逻辑坐标被“重新分配”
// painter.setWindow(0,0,200,200);//
// painter.fillRect(0,0,200,200,Qt::red);
// painter.setViewport(0,0,200,200);
// painter.fillRect(0,0,200,200,Qt::red);
///window 代表窗口坐标,viewport 代表物理坐标。也就是说,
/// 我们将物理坐标区域定义为左上角位于 (0, 0),长高都是 200px 的矩形。
/// 然后还是绘制和上面一样的矩形。如果你认为运行结果是 1/4 窗口被填充,
/// 那就错了。实际是只有 1/16 的窗口被填充。这是由于,
/// 我们修改了物理坐标,但是没有修改相应的窗口坐标。
/// 默认的逻辑坐标范围是左上角坐标为 (0, 0),长宽都是 400px 的矩形。
/// 当我们将物理坐标修改为左上角位于 (0, 0),长高都是 200px 的矩形时,
/// 窗口坐标范围不变,也就是说,我们将物理宽 200px 映射成窗口宽 400px,
/// 物理高 200px 映射成窗口高 400px,所以,原始点 (200, 200) 的坐标变成
/// 了 ((0 + 200 * 200 / 400), (0 + 200 * 200 / 400)) = (100, 100)
/// 我们传给QPainter的是逻辑坐标(也称为世界坐标),逻辑坐标可以通过变换矩阵
/// 转换成窗口坐标,窗口坐标通过 window-viewport 转换成物理坐标(也就是设备坐标)。
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// Widget w;
// w.setFixedSize(400,400);
// w.show();
///QGraphicsScene的sceneRect属性供QGraphicsView确定视图默认的滚动条区域,
/// 并且协助QGraphicsScene管理元素索引。之所以去掉view.resize()一行,
/// 是因为我们让系统去决定视图的最小尺寸(否则的话,我们需要手动将窗口
/// 标题栏等的大小同时考虑设置)
QGraphicsScene scene;
scene.setSceneRect(0,0,300,300);
scene.addLine(0,0,150,150);
QGraphicsView view(&scene);
view.setWindowTitle("Graphics View");
//view.resize(500,500);
view.show();
return a.exec();
}