简介:
Qt中坐标系统是由Qpaint类控制,Qpaint在属于绘图设备中绘制,QpaintDevice类是所有可以绘制图像的基类
QPaintDevice类子类有:
一个绘图设备的默认坐标系统中原点(0, 0)在其左上角,x坐标向右增长,y坐标向下增长。在基于像素的设备上,默认的单位是一个像素,而在打印机上默认的单位是一个点(1/72英寸)。
QPainter的逻辑坐标与绘图设备的物理坐标之间的映射由QPainter的变换矩阵、视口和窗口处理。逻辑坐标和物理坐标默认是一致的。
坐标变换:
基本变换:
默认的,QPainter在相关设备的坐标系统上进行操作,但是它也完全支持仿射(affine)坐标变换在进行绘图时,可以使用QPainter::scale()函数缩放坐标系统;使用QPainter::rotate()函数顺时针旋转坐标系统;使用QPainter::translate()函数平移坐标系统;还可以使用QPainter::shear()围绕原点来扭曲坐标系统。
窗口-视口转换:
Qpaint绘图时,会使用逻辑坐标进行绘制,然后转换到物理坐标。转换依赖QPaint类中worldTransform()函数,viewPort()及window()函数。window(窗口),表示逻辑坐标下一个矩形,viewPort(视口)便是物理坐标下相同的矩形。woldtransform可以是窗口与视口映射函数。默认情况下,逻辑坐标与物理坐标是重合的。
基本变换举例:
绘制一个时钟表(修改来自Qt example)
#include "analogclock.h"
#include <QPainter>
#include <QTime>
#include <QTimer>
#include <QDebug>
AnalogClock::AnalogClock(QWidget *parent)
: QWidget(parent)
{
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update));
timer->start(1000);
setWindowTitle(tr("Analog Clock"));
resize(200, 200);
}
void AnalogClock::paintEvent(QPaintEvent *)
{
static const QPoint hourHand[3] = { //小时表头
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -40)
};
static const QPoint minuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -70)
};
static const QPoint secHand[3] = {
QPoint(7,8),
QPoint(-7,8),
QPoint(0,-90),
};
static const QRect backgroundRect(-100,-100,200,200);
QColor hourColor(127, 0, 127);
QColor minuteColor(0, 127, 127, 191);
QColor secColor(0xef1503);
QColor backgroundColor(0x404142);
int side = qMin(width(), height());
QTime time = QTime::currentTime();
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2); //平移到中心
painter.scale(side / 200.0, side / 200.0); //自适应坐标系统
painter.setPen(Qt::NoPen);
painter.setBrush(backgroundColor);
painter.drawRect(backgroundRect); //绘制暗黑背景
painter.setPen(Qt::NoPen);
painter.setBrush(hourColor);
painter.save();
painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0))); //小时表头指向位置
painter.drawConvexPolygon(hourHand, 3);
painter.restore();
painter.setPen(hourColor);
for (int i = 0; i < 12; ++i) { //轮廓
painter.drawLine(88, 0, 96, 0);
painter.rotate(30.0);
}
painter.setPen(Qt::NoPen);
painter.setBrush(minuteColor);
painter.save();
painter.rotate(6.0 * (time.minute() + time.second() / 60.0));
painter.drawConvexPolygon(minuteHand, 3);
painter.restore();
painter.setPen(minuteColor);
for (int j = 0; j < 60; ++j) {
if ((j % 5) != 0)
painter.drawLine(92, 0, 96, 0);
painter.rotate(6.0);
}
painter.setPen(Qt::NoPen); //绘制秒钟
painter.setBrush(secColor);
painter.save();
painter.rotate(6*time.second());
painter.drawConvexPolygon(secHand,3);
painter.restore();
}
#ifndef ANALOGCLOCK_H
#define ANALOGCLOCK_H
#include <QWidget>
//! [0]
class AnalogClock : public QWidget
{
Q_OBJECT
public:
AnalogClock(QWidget *parent = nullptr);
protected:
void paintEvent(QPaintEvent *event) override;
};
//! [0]
#endif
#include <QApplication>
#include "analogclock.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
AnalogClock clock;
clock.show();
return app.exec();
}
运行效果: