结果预览:

一.代码5个文件

//glwidget.h
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget> class GLWidget:public QGLWidget
{
Q_OBJECT
public:
explicit GLWidget(QWidget *parent = ); int xRotation() const { return xRot; }
int yRotation() const { return yRot; }
int zRotation() const { return zRot; } signals:
void xRotationChanged( int angle);
void yRotationChanged( int angle);
void zRotationChanged( int angle);
public slots:
void setXRotation(int angle);
void setYRotation(int angle);
void setZRotation(int angle);
protected:
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event); private slots:
void alwaysRotate();
void drawTriangle(); private:
void normalizeAngle(int &angle);
int xRot;
int yRot;
int zRot;
QColor faceColors[];
QPoint lastPos;
QColor qtGreen, qtPurple;
}; #endif
//glwidget.cpp
#include <QtGui>
#include <QtOpenGL>
#include<math.h>
#include"glwidget.h" #ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809D
#endif GLWidget::GLWidget(QWidget *parent):QGLWidget(parent)
{ xRot = ;
yRot = ;
zRot = ; faceColors[] = Qt::red;
faceColors[] = Qt::green;
faceColors[] = Qt::blue;
faceColors[] = Qt::yellow; qtGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0); QTimer *timer = new QTimer(this);
connect(timer , SIGNAL(timeout()), this,SLOT(alwaysRotate()));
timer->start();
}
void GLWidget::initializeGL()
{
qglClearColor(qtPurple.dark());
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
glEnable(GL_CULL_FACE); }
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
drawTriangle();
glPopMatrix();
} void GLWidget::resizeGL(int w, int h)
{
int side = qMin(w,h);
glViewport((width() - side) / , (height() - side)/, side, side); glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum( -1.2, 1.2, -1.2, 1.2,5.0, 60.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -40.0); } void GLWidget::mousePressEvent(QMouseEvent *event)
{
lastPos = event->pos();
}
void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
int dx = event->x() - lastPos.x();
int dy = event->y() - lastPos.y(); if (event->buttons()&Qt::LeftButton)
{
setYRotation(yRot + *dy);
} else if (event->buttons()&Qt::RightButton)
{
setZRotation(zRot + *dx);
}
lastPos = event->pos();
} void GLWidget::drawTriangle()
{
static const GLfloat P1[] = { 0.0, -1.0, +2.0 };
static const GLfloat P2[] = { +1.73, -1.0, -1.0 };
static const GLfloat P3[] = { -1.73, -1.0, -1.0 };
static const GLfloat P4[] = { 0.0, +2.0, 0.0 }; static const GLfloat * const coords[][] = {
{ P1, P2, P3 }, { P1, P3, P4 }, { P1, P4, P2 }, { P2, P4, P3 }
};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated( 0.0 , 0.0, -10.0);
glRotatef(xRot, 1.0, 0.0, 0.0);
glRotatef(yRot, 0.0, 1.0, 0.0);
glRotatef(zRot, 0.0, 0.0,1.0); for (int i = ; i != ; ++i)
{
glBegin(GL_TRIANGLES);
qglColor(faceColors[i]);
for (int j = ; j<;++j)
glVertex3f(coords[i][j][], coords[i][j][], coords[i][j][]);
glEnd();
} } void GLWidget::normalizeAngle(int &angle)
{
while (angle<)
angle +=*;
while (angle>*)
angle -=*;
} void GLWidget::setXRotation(int angle)
{
normalizeAngle(angle);
if ( angle!=xRot)
{
xRot = angle;
emit xRotationChanged(angle);
updateGL();
}
}
void GLWidget::setYRotation(int angle)
{
normalizeAngle(angle);
if ( angle != yRot ) {
yRot = angle;
emit yRotationChanged(angle);
updateGL();
}
} void GLWidget::setZRotation(int angle)
{
normalizeAngle(angle);
if ( angle != zRot ) {
zRot = angle;
emit zRotationChanged(angle);
updateGL();
}
} void GLWidget::alwaysRotate()
{
zRot +=;
if (zRot>*) zRot = ;
emit zRotationChanged(zRot);
updateGL();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QMainWindow> class QAction;
class QLabel;
class QMenu;
class QSlider;
class QScrollArea; class GLWidget; class MainWindow : public QMainWindow
{
Q_OBJECT public:
MainWindow(QWidget *parent = );
~MainWindow(); private slots:
void renderIntoPixmap();
void grabFrameBuffer();
void clearPixmap();
void about(); private: void createMenus();
void createActions(); QSlider *createSlider(const char *changedSignal, const char *setterSlot);
void setPixmap(const QPixmap &pixmap);
QSize getSize(); QWidget *centralWidget;
QScrollArea *glWidgetArea;
QScrollArea *pixmapLabelArea;
GLWidget *glWidget;
QLabel *pixmapLabel;
QSlider *xSlider;
QSlider *ySlider;
QSlider *zSlider; QMenu *fileMenu;
QMenu *helpMenu;
QAction *renderIntoPixmapAction;
QAction *grabFrameBufferAction;
QAction *clearPixmapAction;
QAction *exitAction;
QAction *aboutAction;
QAction *aboutQtAction; }; #endif // MAINWINDOW_H
//mainwindow.cpp
#include <QtOpenGL>
#include <QAction>
#include <QLabel>
#include <QMenu>
#include <QSlider>
#include <QScrollArea>
#include <QMenuBar>
#include <QApplication> #include "mainwindow.h"
#include "glwidget.h"
#include <time.h> MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
centralWidget = new QWidget;
setCentralWidget(centralWidget); glWidget = new GLWidget;
pixmapLabel = new QLabel; glWidgetArea = new QScrollArea;
glWidgetArea->setWidget(glWidget);
//glWidgetArea->viewport()->setBackgroundRole(QPalette::Dark);
glWidgetArea->setWidgetResizable(true);
glWidgetArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
glWidgetArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
glWidgetArea->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
glWidgetArea->setMinimumSize(, ); pixmapLabelArea = new QScrollArea;
pixmapLabelArea->setWidget(pixmapLabel);
pixmapLabelArea->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
pixmapLabelArea->setMinimumSize(, ); //在构造一个QSlider时将QGLWidget的信号和槽传给这个函数的形参,这样就可以在QMainWindow中
//控制OpenGL的动作了,而让GLWidget类只完成绘图工作。
xSlider = createSlider(SIGNAL(xRotationChanged(int)),
SLOT(setXRotation(int)));
ySlider = createSlider(SIGNAL(yRotationChanged(int)),
SLOT(setYRotation(int)));
zSlider = createSlider(SIGNAL(zRotationChanged(int)),
SLOT(setZRotation(int))); /*
xSlider = new QSlider(Qt::Horizontal);
ySlider = new QSlider(Qt::Horizontal);
zSlider = new QSlider(Qt::Horizontal);
*/ QGridLayout *centralLayout = new QGridLayout;
centralLayout->addWidget(glWidgetArea, , );
centralLayout->addWidget(pixmapLabelArea, , );
centralLayout->addWidget(xSlider, , , , );
centralLayout->addWidget(ySlider, , , , );
centralLayout->addWidget(zSlider, , , , );
centralWidget->setLayout(centralLayout); createActions();
createMenus(); xSlider->setValue( * );
ySlider->setValue( * );
zSlider->setValue( * ); setWindowTitle(tr("Grabeer"));
resize(, );
} void MainWindow::setPixmap(const QPixmap &pixmap)
{
//截图到磁盘
time_t curTime = time(NULL);
QString path1 = "E:\\",path2=".jpg";
QString path = QString::number(curTime, )+path2; pixmapLabel->setPixmap(pixmap);
pixmap.save(path, , -);
QSize size = pixmap.size();
if (size - QSize(, ) == pixmapLabelArea->maximumViewportSize())
size -= QSize(, );
pixmapLabel->resize(size);
} QSize MainWindow::getSize()
{
bool ok;
QString text = QInputDialog::getText(this, tr("Grabber"),
tr("Enter Pixmap Size:"),
QLineEdit::Normal,
tr("%1 x %2").arg(glWidget->width())
.arg(glWidget->height()),
&ok);
if (!ok)
return QSize(); QRegExp regExp(tr("([0-9]+) *x *([0-9]+)"));
if (regExp.exactMatch(text)) {
int width = regExp.cap().toInt();
int height = regExp.cap().toInt();
if (width > && width < && height > && height < )
return QSize(width, height);
}
return glWidget->size();
} void MainWindow::renderIntoPixmap()
{
QSize size = getSize();
if (size.isValid()) {
QPixmap pixmap = glWidget->renderPixmap(size.width(), size.height());
setPixmap(pixmap);
}
} void MainWindow::grabFrameBuffer()
{
//QGLWidget有一个返回其帧缓冲区的QImage图片的函数
QImage image = glWidget->grabFrameBuffer();
//QPixmap的fromImage函数把一个QImage转换成QPixmap
setPixmap(QPixmap::fromImage(image));
} void MainWindow::clearPixmap()
{
setPixmap(QPixmap()); //给它传一个空的对象
} void MainWindow::about()
{
QMessageBox::about(this, tr("About Grabber"),
tr("The <b>Grabber</b> example demonstrates two approaches for "
"rendering OpenGL into a Qt pixmap."));
} QSlider *MainWindow::createSlider(const char *changedSignal,
const char *setterSlot)
{
QSlider *slider = new QSlider(Qt::Horizontal);
slider->setRange(, * );
slider->setSingleStep();
slider->setPageStep( * );
slider->setTickInterval( * );
slider->setTickPosition(QSlider::TicksRight); //这种经典的用法一定要小心,报错:glWidget的槽函数在传进来的时候已经被强制转换成SLOT了,
//所以setterSlot不用SLOT修饰;同样,changedSignal也不能再拿SIGNAL修饰
connect(slider, SIGNAL(valueChanged(int)), glWidget, setterSlot);
connect(glWidget, changedSignal, slider, SLOT(setValue(int))); return slider;
} void MainWindow::createActions()
{
renderIntoPixmapAction = new QAction(tr("&Render into Pixmap..."), this);
renderIntoPixmapAction->setShortcut(tr("Ctrl+R"));
renderIntoPixmapAction->setToolTip(tr("yes, triggerd it"));
connect(renderIntoPixmapAction, SIGNAL(triggered()),
this, SLOT(renderIntoPixmap())); grabFrameBufferAction = new QAction(tr("&Grab Frame Buffer"), this);
grabFrameBufferAction->setShortcut(tr("Ctrl+G"));
connect(grabFrameBufferAction, SIGNAL(triggered()),
this, SLOT(grabFrameBuffer())); clearPixmapAction = new QAction(tr("&Clear Pixmap"), this);
clearPixmapAction->setShortcut(tr("Ctrl+L"));
connect(clearPixmapAction, SIGNAL(triggered()), this, SLOT(clearPixmap())); exitAction = new QAction(tr("E&xit"), this);
exitAction->setShortcuts(QKeySequence::Quit);
connect(exitAction, SIGNAL(triggered()), this, SLOT(close())); aboutAction = new QAction(tr("&About"), this);
connect(aboutAction, SIGNAL(triggered()), this, SLOT(about())); aboutQtAction = new QAction(tr("About &Qt"), this);
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
} void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(renderIntoPixmapAction);
fileMenu->addAction(grabFrameBufferAction);
fileMenu->addAction(clearPixmapAction);
fileMenu->addSeparator();
fileMenu->addAction(exitAction); helpMenu = menuBar()->addMenu(tr("&Help"));
helpMenu->addAction(aboutAction);
helpMenu->addAction(aboutQtAction);
} MainWindow::~MainWindow()
{
}
//main.cpp
#include <QApplication>
#include <QDesktopWidget> #include "mainwindow.h"
#include "glwidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
window.show();
//GLWidget widegt;
//widegt.show();
return app.exec();
}

二.介绍

1.GLWidget控件类的实现

a.继承QGLWidget类

b.实例虚构OpenGL函数

protected:
void initializeGL();
void paintGL();
void resizeGL(int w, int h);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);

c.根据相关的功能添加函数和变量

d.c++语法两个,其一

int xRotation() const { return xRot; }
int yRotation() const { return yRot; }
int zRotation() const { return zRot; }
//const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰.
//常成员函数, 它不改变对象的成员变量.
//也不能调用类中任何非const成员函数.

其二

explicit GLWidget(QWidget *parent = );
//声明为explicit的构造函数不能在隐式转换中使用。

2.mainwindow类的实现.

a.实现鼠标拖动和slider保持一致.

举个简单的例子:

#include<QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QSpinBox>
int main(int argc, char *argv[])
{
QApplication app(argc, argv); QWidget *window = new QWidget;
window->setWindowTitle("Enter a Number"); QSpinBox *spinbox = new QSpinBox;
QSlider *slider = new QSlider(Qt::Horizontal);
spinbox->setRange(, );
slider->setRange(, ); QObject::connect(spinbox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
QObject::connect(slider,SIGNAL(valueChanged(int)), spinbox, SLOT(setValue(int)));
spinbox->setValue(); QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(spinbox);
layout->addWidget(slider);
window->setLayout(layout); window->show();
return app.exec();
}

b.截图功能实现的工作原理..........

Qt中OpenGL的初步使用的更多相关文章

  1. Qt中OpenGL模块下将图片转化为纹理,并传入shader中

    QImage texture, buffer; buffer.load("C:/Users/wukesong/Pictures/flower.jpg"); texture = QG ...

  2. Qt 框架的图形性能高(OpenGL上的系统效率高),网络性能低,开发效率高,Quick是可以走硬件加速——Qt中分为好几套图形系统,差不多代表了2D描画的发展史。最经典的软描画系统

    -----图形性能部分-----Qt的widgets部分,运行时的图像渲染性能是一般的,因为大部分的界面内容都是Qt自绘,没有走硬件加速,也就是说很多图形内容都是CPU算出来的.但是widgets底层 ...

  3. Ubuntu中在QT中配置OpenGL

    之前搞实验室项目,博客有些天没有更新.现在学习需要,开始搞OpenGL+Ubuntu+QT. 搞了整整一天,由于是首次使用ubuntu,所以这ubuntu下配置qt和Opengl环境时走了很多的弯路, ...

  4. Qt Quick + OpenGL + Bullet初次測试

    Qt Quick + OpenGL + Bullet初次測试 眼下Qt的Quick模块已经表现得很出色,并且可以预留接口来渲染OpenGL场景.一般来说,已经可以满足大部分编程须要了.这次呢.尝试使用 ...

  5. Windows平台下Qt中glut库的使用

    用Qt中的QGLWidget窗体类中是不包括glut工具库的,难怪在myGLWidget(在我的程序中是QGLWidget的派生类)中绘制实心球体是说“glutSolidSphere”: 找不到标识符 ...

  6. Qt中的事件

    1. 引自---http://blog.sina.com.cn/s/blog_6e80f1390100pro4.html 信号和事件的区别就在与,事件比信号更加底层,而且如果一个信号对应多个槽的话,信 ...

  7. 在QT中使用Irrlicht引擎的方法与步骤

      Ø 相关库,插件安装部分 本篇文档介绍在Qt5.2.0下面使用lrrlicht引擎在Qt窗口中输出(开发环境:vs2012) 1. 首先安装好Qt5.2.0,下载地址: http://downlo ...

  8. QT中使用Glut库

    用Qt中的QGLWidget窗体类中是不包括glut工具库的,难怪在myGLWidget(在我的程序中是QGLWidget的派生类)中绘制实心球体是说“glutSolidSphere”: 找不到标识符 ...

  9. Qt 中一些常用类中文说明

    Qt 中一些常用类中文说明是本文讲述的内容,这篇文章主要是介绍Qt 当中经常使用的类,采取的是使用字母索引的方式,下面的类是被经常使用的. QDataStream 为QIODevice提供了一串的二进 ...

随机推荐

  1. HTML中IE条件注释判断语句(<!--[if XX IE X]><![endif]-->)

    <!--[if XX IE X]><![endif]-->是IE专门提供的一种语法,其他浏览器会将其作为注释而忽略这些语句.   作用: 根据不同的IE版本加载对应的CSS或者 ...

  2. Emmet 语法探析

    Emmet 语法探析 Emmet(Zen Coding)是一个能大幅度提高前端开发效率的一个工具. 大多数编辑器都支持Snippet,即存储和重用一些代码块.但是前提是:你必须先定义 这些代码块. E ...

  3. Z - 不容易系列之(3)―― LELE的RPG难题

    Description          人称“AC女之杀手”的超级偶像LELE最近忽然玩起了深沉,这可急坏了众多“Cole”(LELE的粉丝,即"可乐"),经过多方打探,某资深C ...

  4. Codeforces Round #194 (Div. 2) D. Chips

    D. Chips time limit per test:1 second memory limit per test:256 megabytes input:standard input outpu ...

  5. 关于twitter的GIF变mp4的测试

    这个事是好久之前听说了,今天FQ的时候突然想起来了,就去测试了一下这个gif转MP4到底有多神奇... 这个是我的twitter地址:https://twitter.com/chendatony31 ...

  6. PHP解决网站高流量高并发问题

    首先,确认服务器硬件是否足够支持当前的流量. 普通的P4服务器一般最多能支持每天10万独立IP,如果访问量比这个还要大, 那么必须首先配置一台更高性能的专用服务器才能解决问题 ,否则怎么优化都不可能彻 ...

  7. FatMouse' Trade(hdoj1009)

    Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats guarding th ...

  8. Azure File SMB3.0文件共享服务(1)

    Azure Storage File是Azure推出的文件共享服务,目前的版本同时支持SMB 2.1和SMB 3.0协议.文件共享服务非常适合那些希望把自己数据中心中使用文件共享的应用程序,在云端需要 ...

  9. SQL 临时表或表变量替代游标

    1.如果表没有自动增长的标识列(int) 使用临时表 SELECT IDENTITY(int) NewID ,.. INTO #tmp FROM YouTable 2.表有标识列 使用表变量 INSE ...

  10. WindowProc和DefWindowProc的区别

    1. WindowProc是你给自己的窗口定义的窗口处理函数 DefWindowProc是windows平台提供的默认窗口处理函数 如果某些消息你不需要做特别的处理,调用DefWindowProc进行 ...