结果预览:

一.代码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. Winform获取应用程序的当前路径的方法集合(转)

    Winform获取应用程序的当前路径的方法集合,具体如下,值得收藏 //获取当前进程的完整路径,包含文件名(进程名). string str = this.GetType().Assembly.Loc ...

  2. 伪元素”:after” , “:before"

    伪元素就是源码html中不存在,而视觉上又存在的元素     简单用法: blockquote:before {      content: open-quote;      // 其他样式 } // ...

  3. [Effective Modern C++] Item 2. Understand auto type deduction - 了解auto类型推断

    条款二 了解auto类型推断 基础知识 除了一处例外,auto的类型推断与template一样.存在一个直接的从template类型推断到auto类型推断的映射 三类情况下的推断如下所示: // ca ...

  4. linux网络编程:使用单进程实现多客户端通信

    服务端: //回射服务器 //避免僵尸进程 #include "unistd.h" #include "sys/types.h" #include " ...

  5. python-整理-面向对象

    python的类和perl的类有相似之处,类的方法的第一个参数是表示类的对象自己,相当于c#的this python中定义类 class person: ''示例类,人'' count=0; def ...

  6. xstream对象xml互转

    1.引入jar包 xpp3_min-1.1.4c.jarxstream-1.4.8.jar 2.建立java bean package com.jdw.bean; import java.util.A ...

  7. 正式学习 react(三)

    有了基础的webpack基础,我们要对react的基本语法进行学习. 我这个教程全部用es6 实现.可能会忽略一些最基本的语法讲解,这些你在官网上或者其他别的地方都比我讲的全. 今天我要讲一下reac ...

  8. Nginx Http模块开发

    关于Nginx Http模块开发的文章非常少,只有Emiler的那篇关于Http模块的文章,但是那篇文章里面,并没有说到事件型的模块如何进行开发.而且文章里面提到的内容实在是让人有点意犹未尽.因此,对 ...

  9. Nginx 配置指令的执行顺序(三)

    如前文所述,除非像 ngx_set_misc 模块那样使用特殊技术,其他模块的配置指令即使是在 rewrite 阶段运行,也不能和 ngx_rewrite 模块的指令混合使用.不妨来看几个这样的例子. ...

  10. EF6.0 自定义Code First约定

    自定义Code First约定有三种方式,分别是:Lightweight Conventions(轻量级约定).Configuration Conventions(配置型约定).Model-based ...