Run Qt on a thread and draw it in Glut
-
Hi
I'm trying o run Qt on a thread. In my non Qt App, I don't control the main loop. And I want to use Qt. So I render my widget in a QImage and then my app draw its content. I use glut to build working example of what I want to do.
@#include <QtGui/QApplication>
#include <QtGui>
#include <QMutex>
#include <QtOpenGL>
#include <GL/glut.h>int g_width = 400;
int g_height = 400;
GLuint tex;class QtApp : public QThread
{
public:
QtApp()
{int argc = 0;
char** argv = NULL;
app = new QApplication(argc,argv);
bouton = new QPushButton("PushMe");
image = new QImage(g_width,g_height,QImage::Format_ARGB32);
painter= new QPainter(image);
}uchar* getImage()
{
bouton->render(painter);
return image->bits();
}protected:
void run()
{
app->exec();
}
private:
QApplication* app;
QPushButton bouton;
QImage image;
QPainter* painter;
};QtApp* qtapp;
void render(void)
{
//glTexImage2D(GL_TEXTURE_2D,0 , GL_RGBA, g_width, g_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, qtapp->getImage());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_QUADS);
glTexCoord2d(0.0,1.0); glVertex2d(0.0,0.0);
glTexCoord2d(1.0,1.0); glVertex2d(1.0,0.0);
glTexCoord2d(1.0,0.0); glVertex2d(1.0,1.0);
glTexCoord2d(0.0,0.0); glVertex2d(0.0,1.0);glutSwapBuffers();
}void reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (h == 0)h = 1;
gluOrtho2D(0, 1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}int main(int argc, char** argv)
{
qtapp = new QtApp();
qtapp->start();glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(g_width, g_height);
glutCreateWindow("Qt_test");glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glEnable(GL_TEXTURE_2D);glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0 , GL_RGBA, g_width, g_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, qtapp->getImage());glutDisplayFunc(render);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;}@
When I called qtapp->getImage() line 48 and 88 that's render my QPushButton in a QImage, then I send the data to OpenGL to draw it. If I made the call in the main function all is working but if I uncomment the line 48 I get a segfault localize line 27.
Do you think this is due to Qt ? I can look at the source code of glut but I don't know what it could possibly do to interfere whit Qt.
Thanks to reading me.
-
For simple widget rendering you don't need QApplication::exec(), here is an example:
@#include <QtGui>
int main(int argc, char **argv)
{
QApplication app(argc, argv);QPushButton button("test"); button.resize(button.sizeHint()); QImage image(button.rect().size(), QImage::Format_RGB32); image.fill(0xffffffff); QPainter p(& image); button.render(&p); p.end(); image.save("image.png"); return 0;
}
@If you do need input event processing etc from Qt as well, you might still be able to do it in a single thread. What you'd do is use glutIdleFunc() to register a function for GLUT to call when the GLUT event loop is idle. Then you'd call QApplication::processEvents() or potentially QApplication::processEvents(QEventLoop::WaitForMoreEvents, 10) or similar to prevent your application from using too much CPU. 10 is the timeout value in ms, which you might want to tweak a bit to keep the application responsive. Alternatively you could use glutTimerFunc() to call QApplication::processEvents() only every so often.
I would avoid using threads if possible, since that is quite error-prone.