QT的子窗口进行openGL绘制图形,响应键盘事件
(2014-02-17 19:27:52)分类: QT |
这里面主要讲的是使用QT的MainWindow作为主窗口,然后在主窗口中开辟一个子窗口,在这个子窗口中进行OpenGL绘制物体等,然后键盘按下,这个显示OpenGL的子窗口响应键盘事件,例如,按下某个键,子窗口中的物体会旋转等操作。
问题:键盘事件,首先被响应的是MainWindow这个主窗口类,经过一个下午的搜索方法,例如将焦点放在子窗口上,在这个子窗口类中使用keypressevent方法和updateGL方法,依然行不通,最后在QQ的几个专业群里进行求问,得到的答案:子窗口可以响应鼠标事件,
就是不能响应键盘事件,因此只有在MainWindow主窗口类中,用信号槽连接主窗口和子窗口,主窗口中使用keypressevent方法和定义一个信号,在这个方法中触发信号,传递变化的参数,子窗口中写槽事件,接受变化的参数,槽事件中用updateGL方法。
程序如下:
main.cpp:
#include"opengl.h"
#include
intmain( intargc, char*argv[])
{
QApplication a(argc, argv);
"System"); QTextCodec *codec = QTextCodec::codecForName(
QTextCodec::setCodecForLocale(codec);
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
new opengl *w= opengl;
w->show();
return a.exec();
}
opengl.h:
#ifndefOPENGL_H
#defineOPENGL_H
#include
#include
#include"NeHeWidget.h"
classopengl public: QMainWindow
{
Q_OBJECT
public:
opengl(QWidget *parent = 0, Qt::WFlags flags = 0);
~opengl();
privateslots:
void openCloud();
signals:
void angleChanged( float,float);
protected:
void keyPressEvent(QKeyEvent *e);
private:
QMenu* menu;
QAction* open;
QMdiArea* mdiarea;
QMenuBar* bar;
NeHeWidget* cloudwidget;
float rtri;
float qtri;
};
#endif// OPENGL_H
opengl.cpp:
#include"opengl.h"
opengl::opengl(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
new menu= QMenu(tr( "云"),this);
""),tr("打开")); open=menu->addAction(QIcon(
bar=menuBar();
bar->addMenu(menu);
SIGNAL(triggered()),this,SLOT(openCloud())); connect(open,
new mdiarea= QMdiArea;
setCentralWidget(mdiarea);
rtri=0.0;
qtri=0.0;
}
opengl::~opengl()
{
}
voidopengl::openCloud()
{
new cloudwidget= NeHeWidget(0,0);
this,SIGNAL(angleChanged(float,float)),cloudwidget,SLOT(setAngle(float,float))); connect(
QMdiSubWindow* subwindow=mdiarea->addSubWindow(cloudwidget);
"云场"); subwindow->setWindowTitle(
subwindow->resize(800,400);
subwindow->show();
}
voidopengl::keyPressEvent(QKeyEvent *e)
{
switch(e->key()) {
case Qt::Key_S:
rtri+=1.1;
qtri-=1.1;
emit angleChanged(rtri,qtri);
default:
break;
}
}
NeHeWidget.h:
#ifndefNEHEWIDGET_H
#defineNEHEWIDGET_H
#include
classNeHeWidget: publicQGLWidget
{
Q_OBJECT
public:
const NeHeWidget( QWidget* parent = 0, QString title = 0);
void ~NeHeWidget( );
protected:
void InitializeGL( void);
void paintGL( void);
void resizeGL( intwidth, intheight );
protected:
GLfloat rTri;
GLfloat rQuad;
publicslots:
void setAngle( floatrangle, floatqangle);
};
#endif// NEHEWIDGET_H
NeHeWidget.cpp:
#include
#include
#include"NeHeWidget.h"
NeHeWidget::NeHeWidget( QWidget* parent,
const QString title): QGLWidget(parent)
{
setWindowTitle( title );
rTri=0.0;
rQuad=0.0;
}
NeHeWidget::~NeHeWidget(void)
{
}
voidNeHeWidget::InitializeGL( void)
{
glShadeModel( GL_SMOOTH );
glClearColor( 1.0, 1.0, 0.0, 0.0 );
glClearDepth( 1.0 );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
}
voidNeHeWidget::paintGL( void)
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity( );
glTranslatef( -1.5f, 0.0f, -6.0f );
glRotatef(rTri,0.0,1.0,0.0);
glBegin( GL_TRIANGLES );
glColor3f(1.0,0.0,0.0);
glVertex3f( 0.0f, 1.0f, 0.0f );
glColor3f(0.0,1.0,0.0);
glVertex3f( -1.0f, -1.0f, 0.0f );
glColor3f(0.0,0.0,1.0);
glVertex3f( 1.0f, -1.0f, 0.0f );
glEnd( );
glLoadIdentity();
glTranslatef(1.5,0.0,-6.0);
glRotatef(rQuad,1.0,0.0,0.0);
glColor3f(0.5,0.5,1.0);
glBegin( GL_QUADS );
glVertex3f( -1.0f, 1.0f, 0.0f );
glVertex3f( 1.0f, 1.0f, 0.0f );
glVertex3f( 1.0f, -1.0f, 0.0f );
glVertex3f( -1.0f, -1.0f, 0.0f );
glEnd( );
}
voidNeHeWidget::resizeGL( intwidth, intheight )
{
if ( height == 0 )
{
height = 1;
}
glViewport( 0, 0, (GLint)width, (GLint)height );
glMatrixMode( GL_PROJECTION );
glLoadIdentity( );
gluPerspective( 45.0, (GLfloat)width / (GLfloat)height, 0.1, 100 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity( );
}
voidNeHeWidget::setAngle( floatrangle, floatqangle)
{
rTri=rangle;
rQuad=qangle;
this->updateGL();
}
后一篇:QWidget接收键盘事件