QT中使用QPainter 进行自行绘图的时候,为了防止“锯齿”的出现,我们会经常使用抗锯齿属性,也叫反走样, 既:
QPainter::Antialiasing //绘图抗锯齿
QPainter::TextAntialiasing //绘制的字体抗锯齿
QT 只是和很多系统的绘图API一样,提供了抗锯齿的方法,不过抗锯齿的属性默认都是关闭的,QT也不例外。
为了直观的理解抗锯齿(反走样)的作用。我们先给出效果图:
上面的图中,黑色的字体、直线、与上面的圆,都是没有启用抗锯齿(反走样)的效果的; 下面的红色字体、直线、下面的圆都是启用了抗锯齿(反走样)之后的效果。 可以看出,两幅图的效果差别还是挺大的。
我们先来讲一下有关画法的用法
1.画文字
void drawText(const QPointF &p, const QString &s);
void drawText(const QPoint &p, const QString &s);
void drawText(int x, int y, const QString &s);
void drawText(const QPointF &p, const QString &str, int tf, int justificationPadding);
void drawText(const QRectF &r, int flags, const QString &text, QRectF *br = Q_NULLPTR);
void drawText(const QRect &r, int flags, const QString &text, QRect *br = Q_NULLPTR);
void drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br = Q_NULLPTR);
void drawText(const QRectF &r, const QString &text, const QTextOption &o = QTextOption());
可以看出,画文字,有很多种方法,但是无非就是提供文字的坐标,与文字内容。可以根据自己的场景选用不同的方法。
2.画直线
void drawLine(const QLineF &line);
void drawLine(const QLine &line);
void drawLine(int x1, int y1, int x2, int y2);
void drawLine(const QPoint &p1, const QPoint &p2);
void drawLine(const QPointF &p1, const QPointF &p2);
提供起点、终点的坐标就可以了
3.画椭圆(圆)
void drawEllipse(const QRectF &r);
void drawEllipse(const QRect &r);
void drawEllipse(int x, int y, int w, int h);
void drawEllipse(const QPointF ¢er, qreal rx, qreal ry);
void drawEllipse(const QPoint ¢er, int rx, int ry);
其实这个画椭圆的函数,需要制定椭圆所在的矩形框位置。如果指定的矩形框是正方形,画出来就是圆形,否则就是椭圆。
我们的例子中,就是在paintEvent重绘函数中,就是使用了上面三个函数,分别使用 无抗锯齿(反走样), 抗锯齿(反走样),画出了文字、直线、圆,进行对比。
void MyFrame::paintEvent(QPaintEvent *ev)
{
QPainter painter(this);
QBrush brush(Qt::red);
QBrush brush1(Qt::green);
QPen pen(brush1, 5, Qt::DashDotLine, Qt::RoundCap);
/**********************未启用抗锯齿功能**************************/
painter.setPen(Qt::black);
//画字体
painter.drawText(QRectF(20, 30, 100, 100), "这是一行文字");
//画一条没有启用反锯齿的线
painter.drawLine(20, 50, 400, 60);
//画一个圆
painter.setBrush(brush);
painter.setPen(pen);
painter.drawEllipse(20, 55, 150, 150);
/**********************启用抗锯齿功能**************************/
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
painter.setPen(Qt::red);
//画字体
painter.drawText(QRectF(20, 280, 100, 100), "这是一行文字");
//画一条启用反锯齿的线
painter.drawLine(20, 300, 400, 310);
//画一个圆
painter.setPen(pen);
painter.setBrush(brush);
painter.drawEllipse(20, 305, 150, 150);
}
我们看到了,是怎样开启抗锯齿(反走样)功能了,就是这句话
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
前面的 Antialiasing 是绘画普通图形启用反走样, TextAntialiasing是绘画文字反走样。
也可以使用下面的函数进行开启抗锯齿(反走样)功能。
painter.setRenderHint(QPainter::Antialiasing, true);
这里设置Antialiasing属性为true,经过这句设置,我们就打开了反走样功能。QPainter和OPengl一样,是一个状态机。因此,我们这里打开了她,之后所有的代码都是开启反走样绘制的了。若要关闭反走样功能:
painter.setRenderHint(QPainter::Antialiasing, false);
到了这里,我们就会发现,反走样的效果要比走样的好得多。那么为什么系统绘图的API(包含QT在内)为什么默认不打开反走样的呢?这是因为,反走样是一种比较复杂的算法,在一些对图像质量要求不高的应用中,是不需要进行开启反走样的。为了提高效率,一般的图形绘制,都是默认不开启反走样的。
另外一个特别重要的两个属性:画笔QPen 和 画刷 QBrush
QPen : 用于绘制轮廓线
QBrush: 用于填充