Qt-interest Archive, July 2007
GL+Thread Example anyone?
Message 1 in thread
Hi!
I am trying to make the multithreading example for opengl working,
unsuccessfully (OSX 10.4, Qt 4.3, universal binary). It is available
here:
http://doc.trolltech.com/qq/qq06-glimpsing.html#writingmultithreadedglapplications
It
seems that I'm missing some *trivial* point here, I'm almost
embarrassed to ask for help in this matter! The error I'm getting is
the following:
glthread.cpp: In member function 'virtual void GLThread::run()':
glthread.cpp:39: error: invalid use of undefined type 'struct GLWidget'
glthread.h:17: error: forward declaration of 'struct GLWidget'
glthread.cpp:60: error: invalid use of undefined type 'struct GLWidget'
glthread.h:17: error: forward declaration of 'struct GLWidget'
I have declared the classes that are cyclically dependent with a
forward definition, and corrected the errors about the new menu members
in the main application class.
Including the headers, using mixed forward declaration and header
inclusion, making the thread member a pointer do not help. The error
points to the glw->makeCurrent(); call.
Even if it's trivial... I can't find a solution! I know, shame on me :(
Can anyone give me a hint?
Thanks in advance!
/********************************************/
#ifndef GLTHREAD_H
#define GLTHREAD_H
#include <QThread>
#include <QSize>
// Forward declaration for cyclic dependency
class GLWidget;
// Renderer thread class
class GLThread : public QThread
{
public:
GLThread(GLWidget *glWidget);
void resizeViewport(const QSize &size);
void run();
void stop();
private:
bool doRendering;
bool doResize;
int w, h;
int rotAngle;
GLWidget *glw;
};
#endif
/********************************************/
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
// Forward declaration for cyclic dependency
class GLThread;
// Threaded widget
class GLWidget : public QGLWidget
{
public:
GLWidget(QWidget *parent);
void startRendering();
void stopRendering();
protected:
void resizeEvent(QResizeEvent *e);
void paintEvent(QPaintEvent *);
void closeEvent(QCloseEvent *e);
GLThread glt;
};
#endif
--
[ signature omitted ]
Message 2 in thread
try to #include "glwidget.h" in glthread.h and set a forward decl of glthread (as you have it) in glwidget.h.
--st
Sensei wrote:
> Hi!
>
> I am trying to make the multithreading example for opengl working,
> unsuccessfully (OSX 10.4, Qt 4.3, universal binary). It is available here:
>
> http://doc.trolltech.com/qq/qq06-glimpsing.html#writingmultithreadedglapplications
>
>
> It
> seems that I'm missing some *trivial* point here, I'm almost embarrassed
> to ask for help in this matter! The error I'm getting is the following:
>
> glthread.cpp: In member function 'virtual void GLThread::run()':
> glthread.cpp:39: error: invalid use of undefined type 'struct GLWidget'
> glthread.h:17: error: forward declaration of 'struct GLWidget'
> glthread.cpp:60: error: invalid use of undefined type 'struct GLWidget'
> glthread.h:17: error: forward declaration of 'struct GLWidget'
>
>
> I have declared the classes that are cyclically dependent with a forward
> definition, and corrected the errors about the new menu members in the
> main application class.
>
> Including the headers, using mixed forward declaration and header
> inclusion, making the thread member a pointer do not help. The error
> points to the glw->makeCurrent(); call.
>
> Even if it's trivial... I can't find a solution! I know, shame on me :(
>
> Can anyone give me a hint?
> Thanks in advance!
>
> /********************************************/
> #ifndef GLTHREAD_H
> #define GLTHREAD_H
>
> #include <QThread>
> #include <QSize>
>
> // Forward declaration for cyclic dependency
> class GLWidget;
>
> // Renderer thread class
> class GLThread : public QThread
> {
> public:
> GLThread(GLWidget *glWidget);
>
> void resizeViewport(const QSize &size);
> void run();
> void stop();
>
> private:
> bool doRendering;
> bool doResize;
> int w, h;
> int rotAngle;
>
> GLWidget *glw;
> };
>
> #endif
>
>
> /********************************************/
> #ifndef GLWIDGET_H
> #define GLWIDGET_H
>
> #include <QGLWidget>
>
> // Forward declaration for cyclic dependency
> class GLThread;
>
> // Threaded widget
> class GLWidget : public QGLWidget
> {
> public:
> GLWidget(QWidget *parent);
>
> void startRendering();
> void stopRendering();
>
> protected:
> void resizeEvent(QResizeEvent *e);
> void paintEvent(QPaintEvent *);
> void closeEvent(QCloseEvent *e);
>
> GLThread glt;
> };
>
> #endif
>
>
--
[ signature omitted ]
Message 3 in thread
On 2007-07-11 11:58:19 +0200, Stathis <stathis@xxxxxxxxxxxxxxxx> said:
> try to #include "glwidget.h" in glthread.h and set a forward decl of
> glthread (as you have it) in glwidget.h.
If I do so, I get is the error:
glwidget.h:32: error: field 'glt' has incomplete type
I tried also to include "glthread.h" and have glwidget declared. It
passes the first file and it stops again in producing glthread.o with
the error:
glthread.cpp: In member function 'virtual void GLThread::run()':
glthread.cpp:39: error: invalid use of undefined type 'struct GLWidget'
glthread.h:17: error: forward declaration of 'struct GLWidget'
glthread.cpp:68: error: invalid use of undefined type 'struct GLWidget'
glthread.h:17: error: forward declaration of 'struct GLWidget'
I am missing something from that quarterly issue... but I don't see what.
/*********************************************/
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QGLWidget>
// Forward declaration for cyclic dependency
class GLThread;
// Threaded widget
class GLWidget : public QGLWidget
{
public:
GLWidget(QWidget *parent);
void startRendering();
void stopRendering();
protected:
void resizeEvent(QResizeEvent *e);
void paintEvent(QPaintEvent *);
void closeEvent(QCloseEvent *e);
GLThread glt; /* <------- LINE 32 */
};
#endif
/*********************************************/
#ifndef GLTHREAD_H
#define GLTHREAD_H
#include <QThread>
#include <QSize>
#include "glwidget.h"
// Renderer thread class
class GLThread : public QThread
{
public:
GLThread(GLWidget *glWidget);
void resizeViewport(const QSize &size);
void run();
void stop();
private:
bool doRendering;
bool doResize;
int w, h;
int rotAngle;
GLWidget *glw;
};
#endif
--
[ signature omitted ]
Message 4 in thread
> I have declared the classes that are cyclically dependent with a
> forward definition, and corrected the errors about the new menu members
> in the main application class.
You can't forward declare a class if you're going to use it by value as a member of
another class. You have to include the header.
> /********************************************/
> #ifndef GLWIDGET_H
> #define GLWIDGET_H
>
> #include <QGLWidget>
>
> // Forward declaration for cyclic dependency
> class GLThread;
remove the forward declaration and add:
#include "glthread.h"
> // Threaded widget
> class GLWidget : public QGLWidget
> {
> public:
> GLWidget(QWidget *parent);
>
> void startRendering();
> void stopRendering();
>
> protected:
> void resizeEvent(QResizeEvent *e);
> void paintEvent(QPaintEvent *);
> void closeEvent(QCloseEvent *e);
>
> GLThread glt;
> };
The compiler doesn't know how big a GLThread is at this point, because you ahven't
given it a headerfile to figure it out. So, it can't figure out the overall size
of a GLWidget.
In your glthread.h file, you can get away with the forward declaration of GLWidget,
because your member is a pointer, and the compiler knows how much space a pointer
takes up.
--
[ signature omitted ]
Message 5 in thread
On 2007-07-11 13:49:05 +0200, "Caleb Tennis" <caleb@xxxxxxxxxxxx> said:
> remove the forward declaration and add:
> #include "glthread.h"
> The compiler doesn't know how big a GLThread is at this point, because
> you ahven't
> given it a headerfile to figure it out. So, it can't figure out the
> overall size
> of a GLWidget.
>
> In your glthread.h file, you can get away with the forward declaration
> of GLWidget,
> because your member is a pointer, and the compiler knows how much space
> a pointer
> takes up.
It seems reasonable, but it doesn't work.
The application window (which includes the GLWidget header) compiles
fine, but next XCode (as well as the Makefile) compiling the GLThread
class gives the following error:
glthread.cpp: In member function 'virtual void GLThread::run()':
glthread.cpp:39: error: invalid use of undefined type 'struct GLWidget'
glthread.h:17: error: forward declaration of 'struct GLWidget'
glthread.cpp:68: error: invalid use of undefined type 'struct GLWidget'
glthread.h:17: error: forward declaration of 'struct GLWidget'
These two errors point to the calls to the GLWidget class. Here's part
of the implementation that I use. You can see that I'm not using weird
constructs, or at least I'm not aware of this fact, and that it should
work fine (I'm using the exact code from the Qt Quarterly in order to
avoid stupid errors for now).
// Forward declaration of GLWidget in glthread.h
#include "glthread.h"
#include <QTime>
#include <QtOpenGL>
GLThread::GLThread(GLWidget *gl) : QThread(), glw(gl)
{
doRendering = true;
doResize = false;
}
/* ... */
void GLThread::run()
{
srand(QTime::currentTime().msec());
rotAngle = rand() % 360;
/********** FIRST ERROR **********/
glw->makeCurrent();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5.0, 5.0, 5.0, 5.0, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glViewport(0, 0, 200, 200);
glClearColor(0.0, 0.0, 0.0, 1.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
while (doRendering)
{
if (doResize)
{
glViewport(0, 0, w, h);
doResize = false;
}
// Add rendering something
glBegin(GL_QUADS);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, 1.0, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, 1.0);
glEnd();
/********** SECOND ERROR **********/
glw->swapBuffers();
msleep(40);
}
}
--
[ signature omitted ]
Message 6 in thread
> glthread.cpp: In member function 'virtual void GLThread::run()':
> glthread.cpp:39: error: invalid use of undefined type 'struct GLWidget'
> glthread.h:17: error: forward declaration of 'struct GLWidget'
> glthread.cpp:68: error: invalid use of undefined type 'struct GLWidget'
> glthread.h:17: error: forward declaration of 'struct GLWidget'
You haven't shown your revised glthread.h file, but if you made the change I said
and remove the forward declaration from before then you wouldn't be able to get a
forward declaration error on line 17 of glthread.h.
If you did indeed make the change, and are still getting this error, then something
else is wrong. Do you have multiple copies of glthread.h floating around?
--
[ signature omitted ]
Message 7 in thread
On 2007-07-11 14:45:16 +0200, "Caleb Tennis" <caleb@xxxxxxxxxxxx> said:
>> glthread.cpp: In member function 'virtual void GLThread::run()':
>> glthread.cpp:39: error: invalid use of undefined type 'struct GLWidget'
>> glthread.h:17: error: forward declaration of 'struct GLWidget'
>> glthread.cpp:68: error: invalid use of undefined type 'struct GLWidget'
>> glthread.h:17: error: forward declaration of 'struct GLWidget'
>
> You haven't shown your revised glthread.h file, but if you made the
> change I said
> and remove the forward declaration from before then you wouldn't be
> able to get a
> forward declaration error on line 17 of glthread.h.
>
> If you did indeed make the change, and are still getting this error,
> then something
> else is wrong. Do you have multiple copies of glthread.h floating around?
I don't have another copy of glthread.h anywhere, I wish I had! In the
application window class I include just glwidget.h, and you can see
that I'm using a class definition without including the header file.
All the files I have correspond to one class, plus the main function.
sensei:glthreads$ ls
Info.plist glthread.h glwidget.h
appwindow.cpp glthreads.pro main.cpp
appwindow.h glthreads.xcodeproj/
glthread.cpp glwidget.cpp
I can assure you I had actually copied and pasted the code from the web
site, adding two lines to compile it. No fancy things unfortunately...
but of course, there maybe something I totally misunderstood, and
that's the most probable cause.
/*
* glthread.h
*/
#ifndef GLTHREAD_H
#define GLTHREAD_H
#include <QThread>
#include <QSize>
// Forward declaration for cyclic dependency
class GLWidget;
//#include "glwidget.h"
// Renderer thread class
class GLThread : public QThread
{
public:
GLThread(GLWidget *glWidget);
void resizeViewport(const QSize &size);
void run();
void stop();
private:
bool doRendering;
bool doResize;
int w, h;
int rotAngle;
GLWidget *glw;
};
#endif
--
[ signature omitted ]
Message 8 in thread
> On 2007-07-11 14:45:16 +0200, "Caleb Tennis" <caleb@xxxxxxxxxxxx> said:
>
>>> glthread.cpp: In member function 'virtual void GLThread::run()':
>>> glthread.cpp:39: error: invalid use of undefined type 'struct GLWidget'
>>> glthread.h:17: error: forward declaration of 'struct GLWidget'
>>> glthread.cpp:68: error: invalid use of undefined type 'struct GLWidget'
>>> glthread.h:17: error: forward declaration of 'struct GLWidget'
Okay, then this indicates that you aren't including "glwidget.h" in your
glthread.cpp file.
You have to have both #include "glthread.h" and #include "glwidget.h" SOMEWHERE in
your files. If you're forward declaring the classes in the header files, then you
need the includes in your .cpp files.
--
[ signature omitted ]
Message 9 in thread
On 2007-07-11 15:06:30 +0200, "Caleb Tennis" <caleb@xxxxxxxxxxxx> said:
>> On 2007-07-11 14:45:16 +0200, "Caleb Tennis" <caleb@xxxxxxxxxxxx> said:
>>
>>>> glthread.cpp: In member function 'virtual void GLThread::run()':
>>>> glthread.cpp:39: error: invalid use of undefined type 'struct GLWidget'
>>>> glthread.h:17: error: forward declaration of 'struct GLWidget'
>>>> glthread.cpp:68: error: invalid use of undefined type 'struct GLWidget'
>>>> glthread.h:17: error: forward declaration of 'struct GLWidget'
>
> Okay, then this indicates that you aren't including "glwidget.h" in your
> glthread.cpp file.
>
> You have to have both #include "glthread.h" and #include "glwidget.h"
> SOMEWHERE in
> your files. If you're forward declaring the classes in the header
> files, then you
> need the includes in your .cpp files.
Thank you very much, that solved the problem!! This is a very stupid
error, shame on me! :)
--
[ signature omitted ]
Message 10 in thread
Caleb is exactly right here. You can only use the forward decl with a pointer, I didn't see it.
Also note that I have the very same implementation with glwidgets/rendering threads which works fine, with the one class
forward declared and the other with an included header. Typically my setup is like this:
glthread.h
glthread.cpp (this #include "glthread.h")
glwidget.h
glwidget.cpp (this #include "glwidget.h")
You must have all these files in your .pro in the respective HEADERS/SOURCES defined.
Then in glwidget.h there is => class GLThread; // forward declaration
and in glthread.h there is => #include "glwidget.h"
sure you can come up with other combination, but it works fine for me like this.
--stathis
Caleb Tennis wrote:
>> I have declared the classes that are cyclically dependent with a
>> forward definition, and corrected the errors about the new menu members
>> in the main application class.
>
> You can't forward declare a class if you're going to use it by value as a member of
> another class. You have to include the header.
>
>> /********************************************/
>> #ifndef GLWIDGET_H
>> #define GLWIDGET_H
>>
>> #include <QGLWidget>
>>
>> // Forward declaration for cyclic dependency
>> class GLThread;
>
>
> remove the forward declaration and add:
> #include "glthread.h"
>
>
>> // Threaded widget
>> class GLWidget : public QGLWidget
>> {
>> public:
>> GLWidget(QWidget *parent);
>>
>> void startRendering();
>> void stopRendering();
>>
>> protected:
>> void resizeEvent(QResizeEvent *e);
>> void paintEvent(QPaintEvent *);
>> void closeEvent(QCloseEvent *e);
>>
>> GLThread glt;
>> };
>
> The compiler doesn't know how big a GLThread is at this point, because you ahven't
> given it a headerfile to figure it out. So, it can't figure out the overall size
> of a GLWidget.
>
> In your glthread.h file, you can get away with the forward declaration of GLWidget,
> because your member is a pointer, and the compiler knows how much space a pointer
> takes up.
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>
--
[ signature omitted ]
Message 11 in thread
hi,
I am having problems with my signals and slots again.
when I compile my application, I don't have any problem, but when I
launch it, I get this error message:
QObject::connect: No such slot QGLViewer::loadNew(const QString&)
Any ideas?
Thanks,
Marie
----------------------
My code:
in *object_ui.cpp* generated automatically with a .ui file
#include "interface.h"
...
interface1 = new Interface( centralWidget(), "interface1" );
...
connect( this, SIGNAL( fileChanged(const QString &) ), interface1,
SLOT( loadNew(const QString&) ) );
my *interface.h* file:
#include <QGLViewer/qglviewer.h>
using namespace qglviewer;
class Interface : public QGLViewer
{
public :
#if QT_VERSION < 0x040000
Interface ( QWidget *parent, const char *name );
#else
Interface ( QWidget *parent );
#endif
public slots:
void loadNew(const QString & fileName);
...
my *interface.cpp* file:
void Interface::loadNew(const QString & fileName)
{
/// @todo implement me
isLoaded=FALSE;
load ( fileName );
draw();
}
--
[ signature omitted ]
Message 12 in thread
Marie-Christine Vallet wrote:
>
> hi,
> I am having problems with my signals and slots again.
> when I compile my application, I don't have any problem, but when I
> launch it, I get this error message:
>
> QObject::connect: No such slot QGLViewer::loadNew(const QString&)
>
> Any ideas?
> Thanks,
> Marie
> ----------------------
> My code:
>
>
> in *object_ui.cpp* generated automatically with a .ui file
>
>
> #include "interface.h"
> ...
>
> interface1 = new Interface( centralWidget(), "interface1" );
> ...
> connect( this, SIGNAL( fileChanged(const QString &) ), interface1,
> SLOT( loadNew(const QString&) ) );
>
>
>
>
>
> my *interface.h* file:
>
> #include <QGLViewer/qglviewer.h>
>
>
> using namespace qglviewer;
>
> class Interface : public QGLViewer
> {
> public :
> #if QT_VERSION < 0x040000
> Interface ( QWidget *parent, const char *name );
> #else
> Interface ( QWidget *parent );
> #endif
>
> public slots:
> void loadNew(const QString & fileName);
this needs to be:
void loadNew(const QString &);
Basically the declaration of the slot in your interface should match the
connect() line exactly.
You only need put the variable name in the implementation.
- Keith
--
[ signature omitted ]
Message 13 in thread
Hi,
>> public slots:
>> void loadNew(const QString & fileName);
> this needs to be:
> void loadNew(const QString &);
>
> Basically the declaration of the slot in your interface should match the
> connect() line exactly.
> You only need put the variable name in the implementation.
Qt itself uses variable names in slot declarations, I don't think that's the
problem. For example qwidget.h:
public slots:
// Widget management functions
virtual void setVisible(bool visible);
The problem seems to be a missing Q_OBJECT in class Interface.
--
[ signature omitted ]
Message 14 in thread
Keith Sabine wrote:
>
>>
>> my *interface.h* file:
>>
>> #include <QGLViewer/qglviewer.h>
>>
>>
>> using namespace qglviewer;
>>
>> class Interface : public QGLViewer
>> {
>> public :
>> #if QT_VERSION < 0x040000
>> Interface ( QWidget *parent, const char *name );
>> #else
>> Interface ( QWidget *parent );
>> #endif
>>
>> public slots:
>> void loadNew(const QString & fileName);
> this needs to be:
> void loadNew(const QString &);
>
> Basically the declaration of the slot in your interface should match
> the connect() line exactly.
> You only need put the variable name in the implementation.
>
Umm, I'm talking tosh. You're missing the Q_OBJECT macro....
- Keith
--
[ signature omitted ]
Message 15 in thread
On 11.07.07 10:45:27, Marie-Christine Vallet wrote:
> I am having problems with my signals and slots again.
> when I compile my application, I don't have any problem, but when I launch it,
> I get this error message:
>
> QObject::connect: No such slot QGLViewer::loadNew(const QString&)
>
> Any ideas?
a) Please don't steal other people's threads by hitting reply and
clearing the mail and subject. Open a new mail for a new topic.
b) You're missing the Q_OBJECT macro in your Interface class, which
means moc will not generate the signal/slot stuff so all you have is a
normal member function, but no slot.
Andreas
--
[ signature omitted ]