Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 2

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 ]