《QTCreator快速入门》第十二章:3D绘图

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《QTCreator快速⼊门》第⼗⼆章:3D绘图
OpenGL是⼀套跨平台的⽤来渲染3D图形的API。

OpenGL⾃⾝是⼀个巨⼤的状态机:⼀系列的变量描述OpenGL此刻应当如何运⾏,OpenGL的状态通常被称为OpenGL上下⽂(Context)。

我们通常使⽤如下途径去更改OpenGL状态:设置选项,操作缓冲,最后,我们使⽤当前OpenGL上下⽂来渲染。

假设当我们想告诉OpenGL去画线段⽽不是三⾓形的时候,我们通过改变⼀些上下⽂变量来改变OpenGL状态,从⽽告诉OpenGL如何去绘图。

⼀旦我们改变了OpenGL的状态为绘制线段,下⼀个绘制命令就会画出线段⽽不是三⾓形。

当使⽤OpenGL的时候,我们会遇到⼀些状态设置函数,这类函数将会改变上下⽂。

以及状态使⽤函数,这类函数会根据当前OpenGL的状态执⾏⼀些操作。

⽐如下⾯例⼦中的glClearColor()函数是⼀个状态设置函数,⽽glClear()函数则是⼀个状态使⽤的函数,它使⽤了当前的状态来获取应该清除为的颜⾊。

Qt中的QtOpenGL模块提供了使⽤OpenGL的⽅法,使⽤它需要在.pro项⽬⽂件中添加QT+=opengl。

QGLWidget是QtOpenGL模块中的⼀个类,它是⼀个⽤来渲染OpenGL图形的部件,可以继承该类后来像使⽤其它QWidget部件⼀样使⽤它。

QGLWidget提供了3个虚函数重写它们来实现指定操作:
initializeGL():设置OpenGL渲染环境,定义显⽰列表等,只在resizeGL()、paintGL()之前被调⽤⼀次。

resizeGL():设置OpenGL的视⼝,投影等,部件⼤⼩改变的时候被调⽤。

paintGL():渲染OpenGL场景,当部件需要更新时被调⽤。

Qt中有⼀个Hello GL⽰例程序,它在OpenGL分类中。

1、基本绘制
下⾯代码使⽤QGLWidget绘制了⼀个直线、三⾓形、⽂本,其中的MyGLWidget继承⾃QGLWidget:
#include <QApplication>
#include "myglwidget.h"
int main(int argc, char**argv)
{
QApplication app(argc, argv);
MyGLWidget w;
w.resize(600, 400);
w.show();
return app.exec();
}
View Code
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
#include <QGLWidget>
#include <GL/glu.h>
class MyGLWidget: public QGLWidget
{
void initializeGL()
{
//void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha);
glClearColor(1.0, 0.0, 0.0, 0.0); //设置清除屏幕(glClear()⽅法)时使⽤的颜⾊为红⾊
glShadeModel(GL_SMOOTH); //设置阴影平滑
//void glClearDepth(GLclampd depth);
glClearDepth(1.0); //设置深度缓存(深度缓冲区中每个像素需要的值)
glEnable(GL_DEPTH_TEST); //启⽤深度测试功能,根据坐标的远近⾃动隐藏被遮住的图形(材料)
}
void resizeGL(int w, int h)
{
//设置视⼝的⼤⼩:告诉OpenGL渲染窗⼝的尺⼨⼤⼩
//也可以将视⼝的维度设置为⽐窗⼝的维度⼩,这样OpenGL渲染将会在⼀个⼩窗⼝中显⽰,这样⼦我们也可以将⼀些其它元素显⽰在OpenGL视⼝之外
glViewport(0, 0, (GLint)w, (GLint)h);
glMatrixMode(GL_PROJECTION); //投影矩阵模式
glLoadIdentity(); //重置当前指定的矩阵为单位矩阵,这样可以将矩阵恢复到初始状态。

gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 0.1, 100.0); //设置透视投影矩阵:视⾓为45度,纵横⽐为窗⼝的纵横⽐,最近和最远的位置分别为0.1和100
glMatrixMode(GL_MODELVIEW); //设置模型视图矩阵
glLoadIdentity(); //重置模型视图矩阵
}
void paintGL()
{
//在每个新的渲染迭代开始的时候我们总是希望清屏,否则我们仍能看见上⼀次迭代的渲染结果
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕:使⽤glClearColor()设置的颜⾊和glClearDepth()设置的深度缓存
glLoadIdentity(); //重置模型视图矩阵,这样便将坐标原点移到了窗⼝中⼼
GLfloat z_translate = -6.0;
//void glTranslatef(GLfloat x,GLfloat y,GLfloat z);
//移动坐标原点,是相对于当前点来移动的,对于z来说正数为向屏幕外移动(相当于在眼睛后⽅,所以就看不到了),负数为向屏幕内移动(绝对值越⼤离眼睛越远,看起来越⼩) glTranslatef(0.0, 0.0, z_translate); //将坐标原点内移6.0
glBegin(GL_LINES); //开始绘制直线
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glEnd();
glBegin(GL_TRIANGLES); //开始绘制三⾓形
//逆时针绘制各顶点
//void glVertex3f(GLfloat x,GLfloat y,GLfloat z);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glEnd();
//void renderText(double x, double y, double z, const QString & str,
// const QFont & fnt = QFont(), int listBase = 2000);
renderText(0.0, 2.0, 0.0, "test"); //绘制⽂本
}
};
#endif// MYGLWIDGET_H
View Code
下⾯分别是z_translate为-6、-4、-2、-0.1、-0.09时的效果,可以看到其绝对值越⼩,即为离眼睛越来越近,所以看起来越⼤,⽽如果其绝对值⼩于gluPerspective()设置的最近位置则就看不见了。

⽽如果将z_translate设为正值的话相当于是在眼睛的后⽅,这样更不能看见了:
void glMatrixMode(GLenum mode):将当前矩阵设置成参数所指定的模式,以满⾜不同绘图所需执⾏的矩阵变换。

glMatrixMode()其实就是对接下来要做什么进⾏⼀下声明,参数mode指定哪⼀个矩阵堆栈是下⼀个矩阵操作的⽬标:
GL_MODELVIEW, 对模型视图矩阵堆栈应⽤随后的矩阵操作。

可以在执⾏此命令后,输出⾃⼰的物体图形了。

在需要绘制出对象或要对所绘制对象进⾏⼏何变换时,需要将变换矩阵设置成模型视图模式;
GL_PROJECTION, 对投影矩阵堆栈应⽤随后的矩阵操作。

可以在执⾏此命令后,为我们的场景增加透视。

当需要对绘制的对象设置某种投影⽅式时,则需要将变换矩阵设置成投影模式;
GL_TEXTURE, 对纹理矩阵堆栈应⽤随后的矩阵操作。

可以在执⾏此命令后,为我们的图形增加纹理贴图。

在进⾏纹理映射时,才需要将变换矩阵设置成纹理模式。

void gluPerspective(GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar):设置矩阵:
fovy是眼睛上下睁开的幅度,⾓度值,值越⼩,视野范围越狭⼩(眯眼),感觉物体越近,值越⼤,视野范围越宽阔(睁⼤眼),感觉物体越远;
aspect表⽰裁剪⾯的宽w⾼h⽐,这个影响到视野的截⾯有多⼤。

zNear表⽰近裁剪⾯到眼睛的距离,zFar表⽰远裁剪⾯到眼睛的距离,注意zNear和zFar不能设置设置为负值(你怎么看到眼睛后⾯的东西),离眼睛越近东西看起来就越⼤
QGLWidget下还有⼀个renderPixmap()⽅法,使⽤它可以获得指定矩形的截图(QPixmap),然后可以使⽤QPixmap的save()来保存该截图。

还可以设置绘制的时候各个顶点使⽤的颜⾊,如下所⽰:
void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕:使⽤glClearColor()设置的颜⾊和glClearDepth()设置的深度缓存
glLoadIdentity(); //重置模型视图矩阵,这样便将坐标原点移到了窗⼝中⼼
GLfloat z_translate = -6.0;
//void glTranslatef(GLfloat x,GLfloat y,GLfloat z);
glTranslatef(-2.0, 0.0, z_translate); //将坐标原点左移2.0,内移6.0
glBegin(GL_TRIANGLES); //开始绘制三⾓形
//逆时针绘制各顶点
//void glVertex3f(GLfloat x,GLfloat y,GLfloat z);
glColor3f(1.0, 0.0, 0.0); //红⾊
glVertex3f(0.0, 1.0, 0.0);
glColor3f(0.0, 1.0, 0.0); //绿⾊
glVertex3f(-1.0, -1.0, 0.0);
glColor3f(0.0, 0.0, 1.0); //蓝⾊
glVertex3f(1.0, -1.0, 0.0);
glEnd();
glTranslatef(4.0, 0.0, 0.0); //将坐标原点右移4.0
glBegin(GL_QUADS); //开始绘制四边形
//顺时针绘制各顶点
glColor3f(1.0, 1.0, 0.0); //黄⾊
glVertex3f(-1.0, 1.0, 0.0);
glVertex3f(1.0, 1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glEnd();
}
View Code
2、3D效果绘制
下⾯的代码绘制了⼀个⽴⽅体的三⾯,使⽤上、下、左、右、4、6键分别沿X轴向上、向下、沿Y轴向左、向右、沿Z轴向左、向右,使⽤8和2键进⾏缩⼩和放⼤:
class MyGLWidget : public QGLWidget
{
public:
MyGLWidget();
protected:
void initializeGL()override;
void resizeGL(int w, int h)override;
void paintGL()override;
void keyPressEvent(QKeyEvent*)override;
private:
GLfloat translate = -6.0, xRot = 0.0, yRot = 0.0, zRot = 0.0;
};
View Code
#include "myglwidget.h"
#include<GL/glu.h>
#include <QKeyEvent>
MyGLWidget::MyGLWidget()
{
}
void MyGLWidget::initializeGL()
{
//void glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha);
glClearColor(1.0, 0.0, 0.0, 0.0); //设置清除屏幕时使⽤的颜⾊为红⾊
glShadeModel(GL_SMOOTH); //设置阴影平滑
//void glClearDepth(GLclampd depth);
glClearDepth(1.0); //设置深度缓存(深度缓冲区中每个像素需要的值)
glEnable(GL_DEPTH_TEST); //启⽤深度测试功能,根据坐标的远近⾃动隐藏被遮住的图形(材料)
}
void MyGLWidget::resizeGL(int w, int h)
{
glViewport(0, 0, (GLint)w, (GLint)h); //设置视⼝的⼤⼩
glMatrixMode(GL_PROJECTION); //投影矩阵模式
glLoadIdentity(); //重置当前指定的矩阵为单位矩阵,这样可以将矩阵恢复到初始状态。

gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 0.1, 100.0); //设置透视投影矩阵:视⾓为45度,纵横⽐为窗⼝的纵横⽐,最近和最远的位置分别为0.1和100
glMatrixMode(GL_MODELVIEW); //设置模型视图矩阵
glLoadIdentity(); //重置模型视图矩阵
}
void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//坐标原点沿Z轴移动translate,正数为向屏幕外移,负数为向屏幕内移,向屏幕外移相当于离眼睛越来越近所以更⼤
glTranslatef(0.0, 0.0, translate);
//void glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z);
glRotatef(xRot, 1.0, 0.0, 0.0); //绕X轴旋转到xRot度(正数为逆时针、负数为顺时针), glRotatef(xRot, -1.0, 0.0, 0.0)为绕X轴旋转到xRot度(负数为逆时针、正数为顺时针)
glRotatef(yRot, 0.0, 1.0, 0.0); //绕Y轴旋转到yRot度
glRotatef(zRot, 0.0, 0.0, 1.0); //绕Z轴旋转到zRot度
glBegin(GL_QUADS);
//逆时针(从上往下看)绘制正⽅体的上⾯
glColor3f(1.0, 1.0, 0.0); //黄⾊
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(-1.0, 1.0, 1.0);
//逆时针(从上往下看)绘制正⽅体的下⾯
glColor3f(0.0, 1.0, 0.0); //绿⾊
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, 1.0);
//逆时针绘制正⽅体的前⾯
glColor3f(0.0, 0.0, 1.0); //蓝⾊
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glEnd();
}
void MyGLWidget::keyPressEvent(QKeyEvent* event)
{
switch (event->key()) {
case Qt::Key_Up:
xRot -= 10;
break;
case Qt::Key_Down:
xRot += 10;
break;
case Qt::Key_Left:
yRot -= 10;
break;
case Qt::Key_Right:
yRot += 10;
break;
case Qt::Key_4:
zRot += 10;
break;
case Qt::Key_6:
zRot -= 10;
break;
case Qt::Key_8:
if(--translate <= -20)
translate = -1;
break;
case Qt::Key_2:
if(++translate >= -1)
translate = -20;
break;
}
updateGL(); //更新绘制
QGLWidget::keyPressEvent(event);
}
View Code
3、使⽤纹理贴图
使⽤纹理贴图可以参考Qt中的Textures⽰例程序。

#include <QGLWidget>
class MyGLWidget : public QGLWidget
{
public:
MyGLWidget();
protected:
void initializeGL()override;
void resizeGL(int w, int h)override;
void paintGL()override;
void keyPressEvent(QKeyEvent*)override;
private:
GLfloat translate = -6.0, xRot = 0.0, yRot = 0.0, zRot = 0.0;
GLuint textures[3]; //存储纹理
};
View Code
void MyGLWidget::initializeGL()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
//创建并绑定纹理
textures[0] = bindTexture(QPixmap("F://side1.png"));
textures[1] = bindTexture(QPixmap("F://side2.png"));
textures[2] = bindTexture(QPixmap("F://side3.png"));
glEnable(GL_TEXTURE_2D); //开启2D纹理贴图功能
}
......
void MyGLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0, 0.0, translate);
glRotatef(xRot, 1.0, 0.0, 0.0);
glRotatef(yRot, 0.0, 1.0, 0.0);
glRotatef(zRot, 0.0, 0.0, 1.0);
//绘制正⽅体的上⾯
glBindTexture(GL_TEXTURE_2D, textures[2]); //绑定纹理
glBegin(GL_QUADS); //更改使⽤的纹理必须再次使⽤glBegin()来开始⼀个新的绘图
//void glTexCoord2f(GLfloat s,GLfloat t); //设置纹理的坐标,应该在每次绘制顶点前调⽤它,纹理的四个顶点应该与四边形四个顶点正确对应
glTexCoord2f(1.0, 0.0); //第⼀个参数是X坐标(0.0为纹理的最左侧,1.0为纹理的最右侧),第⼆个参数是Y坐标(0.0为纹理的底部,1.0为纹理的顶部)
glVertex3f(1.0, 1.0, 1.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0);
glEnd();
//绘制正⽅体的下⾯
glBindTexture(GL_TEXTURE_2D, textures[1]);
glBegin(GL_QUADS);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0);
glEnd();
//绘制正⽅体的前⾯
glBindTexture(GL_TEXTURE_2D, textures[0]);
glBegin(GL_QUADS);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 1.0);
glEnd();
}
......
View Code
可以看到图形下⾯的2看起来是倒置的,因为我们绘制的时候是从上往下看的,将纹理的(0.0, 0.0)顶点和(0.0, 1.0)顶点对置、(1.0, 0.0)顶点和(1.0, 1.0)顶点对置即可,如下所⽰:
......
//绘制正⽅体的下⾯
glBindTexture(GL_TEXTURE_2D, textures[1]);
glBegin(GL_QUADS);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);
glEnd();
......
View Code
4、在3D场景中绘制2D图形
QGLWidget可以实现3D场景绘图,⽽QGLWidget也是⼀个QWidget部件,所以也可以进⾏2D绘图,可以参考Overpainting⽰例程序。

如下所⽰的⽰例先在构造函数中调⽤setAutoFillBackground(),然后在keyPressEvent()中将updateGL()替换为update(),然后将initializeGL()、resizeGL()、paintGL()中代码剪切到新的⽅法中后在paintEvent()⽅法中添加对它们的调⽤:
class MyGLWidget : public QGLWidget
{
public:
MyGLWidget();
protected:
void initializeGL()override;
void resizeGL(int w, int h)override;
void paintGL()override;
void keyPressEvent(QKeyEvent*)override;
void paintEvent(QPaintEvent*)override;
void initializeGL2();
void resizeGL2(int w, int h);
void paintGL2();
private:
GLfloat translate = -6.0, xRot = 0.0, yRot = 0.0, zRot = 0.0;
GLuint textures[3];
};
View Code
MyGLWidget::MyGLWidget()
{
setAutoFillBackground(false); //关闭⾃动填充背景
}
void MyGLWidget::initializeGL()
{
}
void MyGLWidget::resizeGL(int w, int h)
{
}
void MyGLWidget::paintGL()
{
}
void MyGLWidget::initializeGL2()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
textures[0] = bindTexture(QPixmap("F://side1.png"));
textures[1] = bindTexture(QPixmap("F://side2.png"));
textures[2] = bindTexture(QPixmap("F://side3.png"));
glEnable(GL_TEXTURE_2D);
}
void MyGLWidget::resizeGL2(int w, int h)
{
glViewport(0, 0, (GLint)w, (GLint)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLint)w / (GLint)h, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void MyGLWidget::paintGL2()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity();
glTranslatef(0.0, 0.0, translate);
glRotatef(xRot, 1.0, 0.0, 0.0);
glRotatef(yRot, 0.0, 1.0, 0.0);
glRotatef(zRot, 0.0, 0.0, 1.0);
glBindTexture(GL_TEXTURE_2D, textures[2]);
glBegin(GL_QUADS);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, 1.0, 1.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0);
glEnd();
glBindTexture(GL_TEXTURE_2D, textures[1]);
glBegin(GL_QUADS);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 1.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, -1.0, -1.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0);
glEnd();
glBindTexture(GL_TEXTURE_2D, textures[0]);
glBegin(GL_QUADS);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 1.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 1.0);
glEnd();
}
void MyGLWidget::keyPressEvent(QKeyEvent* event)
{
switch (event->key()) {
case Qt::Key_Up:
xRot -= 10;
break;
case Qt::Key_Down:
xRot += 10;
break;
case Qt::Key_Left:
yRot -= 10;
break;
case Qt::Key_Right:
yRot += 10;
break;
case Qt::Key_4:
zRot += 10;
break;
case Qt::Key_6:
zRot -= 10;
break;
case Qt::Key_8:
if(--translate <= -20)
translate = -1;
break;
case Qt::Key_2:
if(++translate >= -1)
translate = -20;
break;
}
update(); //更新绘制
QGLWidget::keyPressEvent(event);
}
void MyGLWidget::paintEvent(QPaintEvent*)
{
makeCurrent(); //在当前窗⼝中进⾏OpenGL的绘制
glMatrixMode(GL_MODELVIEW); //将模型视图矩阵压⼊堆栈 glPushMatrix();
initializeGL2();
resizeGL2(width(), height());
paintGL2();
//关闭启⽤的功能并弹出模型视图矩阵
glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
//进⾏2D绘图
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(Qt::yellow);
painter.drawRect(0, 0, 100, 100);
painter.end();
}
View Code。

相关文档
最新文档