PDA

View Full Version : QMainWindow - issue



sajis997
9th March 2012, 22:54
Hello forum

I have subclass the QMainWindow and it contains another widget as a central widget. The size of the central widget depends on the size of the widget. I am trying to set the widget size inside the constructor of the subclassed QMainWindow.





//GETTING ERROR ON THE FOLLOWING TWO LINES
int width = sizeHint().width();
int height = sizeHint().height();

//set width and height of the glwindow - WHICH IS THE WIDGET OF ANOTHER TYPE
m_glWindow->width->setValue(width);
m_glWindow->height->setValue(height);

setCentralWidget(m_glWindow);



The error that i got is :




H3DMainWindow.cpp:24: warning: when initialized here
H3DMainWindow.cpp:52: error: request for member ‘width’ is ambiguous
/usr/local/Trolltech/Qt-4.8.0/include/QtGui/qpaintdevice.h:91: error: candidates are: int QPaintDevice::width() const
/usr/local/Trolltech/Qt-4.8.0/include/QtGui/qwidget.h:1026: error: int QWidget::width() const
/usr/local/include/H3D/H3DWindowNode.h:267: error: std::auto_ptr<H3D::SFInt32> H3D::H3DWindowNode::width
H3DMainWindow.cpp:53: error: request for member ‘height’ is ambiguous
/usr/local/Trolltech/Qt-4.8.0/include/QtGui/qpaintdevice.h:92: error: candidates are: int QPaintDevice::height() const
/usr/local/Trolltech/Qt-4.8.0/include/QtGui/qwidget.h:1029: error: int QWidget::height() const
/usr/local/include/H3D/H3DWindowNode.h:273: error: std::auto_ptr<H3D::SFInt32> H3D::H3DWindowNode::height
H3DMainWindow.cpp: At global scope:
H3DMainWindow.cpp:369: warning: unused parameter ‘fileName’
make: *** [H3DMainWindow.o] Error 1
sajjad@sajjad:~/Documents/H3DViewer$





Any hint to get around ?



Regards
Sajjad

ChrisW67
10th March 2012, 00:18
I think you will find that the error messages are related to the later two lines:


//set width and height of the glwindow - WHICH IS THE WIDGET OF ANOTHER TYPE
m_glWindow->width->setValue(width);
m_glWindow->height->setValue(height);

and that the m_glWindow widget (a QGLWidget perhaps?) has no member variable called width/height. When the compiler looks for "width" it finds two options and doesn't know which you mean. (How you arrived at the code you wrote is a mystery to me.) I think you probably wanted:


m_glWindow->resize(width, height);


The exercise is probably pointless because making the m_glWindow the centralWidget() will make it fill the client area of the main window anyway. It may also adjust the size hint.

sajis997
12th March 2012, 08:33
Hi

It is not a QGLWidget subclass as you have assumed. It is a subclass of another class of a third-party API called H3DWindowNode and i checked that it has the member called width and height. To make it the central widget i have customized as follows:



class MyH3DCanvasWindow : public H3D::H3DWindowNode, public QWidget
{
public:




All i want is to sent the current window's width and height to the third-party API member variable.

Any more hint? Let me know if you need more information.


Regards
Sajjad

Added after 20 minutes:

Hi again,

A more complete error message might help to point out the reason of the error




H3DMainWindow.cpp:52: error: request for member ‘width’ is ambiguous
/usr/local/Trolltech/Qt-4.8.0/include/QtGui/qpaintdevice.h:91: error: candidates are: int QPaintDevice::width() const
/usr/local/Trolltech/Qt-4.8.0/include/QtGui/qwidget.h:1026: error: int QWidget::width() const
/usr/local/include/H3D/H3DWindowNode.h:267: error: std::auto_ptr<H3D::SFInt32> H3D::H3DWindowNode::width
H3DMainWindow.cpp:53: error: request for member ‘height’ is ambiguous
/usr/local/Trolltech/Qt-4.8.0/include/QtGui/qpaintdevice.h:92: error: candidates are: int QPaintDevice::height() const
/usr/local/Trolltech/Qt-4.8.0/include/QtGui/qwidget.h:1029: error: int QWidget::height() const
/usr/local/include/H3D/H3DWindowNode.h:273: error: std::auto_ptr<H3D::SFInt32> H3D::H3DWindowNode::height
H3DMainWindow.cpp: At global scope:
H3DMainWindow.cpp:370: warning: unused parameter ‘fileName’
make: *** [H3DMainWindow.o] Error 1





Thanks
Sajjad

ChrisW67
12th March 2012, 09:05
Excellent, it may not be a QGLWidget, but the problem is exactly as I expected.

Your MyH3DCanvasWindow inherits a member variable called width from H3D::H3DWindowNode, and a two width() methods via QWidget. You try to use width and the compiler has three ambiguous choices. You need to rethink what you are trying to achieve by mashing the two classes together.

sajis997
12th March 2012, 18:06
Hi,

I am trying figure out as well how to port this WxWidget application to Qt. Now i am attaching the UML diagram so that you can provide me with more insight to design is Qt equivalent.

Please make some some to go through it. Let me explain the image again.7492

Here the H3DWindowNode is the third-party class and its subclass seems to be the central widget in this wxwidget application. This subclass contains reference to other class which in turn are subclasses of wxWidget classes.


If you need any more explanation, please shoot!

Thanks

Sajjad

wysota
12th March 2012, 23:13
Ok but why do you insist on inheriting the H3DWindowNode class in your widget class? Why not use composition instead of inheritance? The fact that the application you are trying to port had such design doesn't mean the same design will fit a different application framework such as Qt.

sajis997
13th March 2012, 00:01
Hi

Thanks for the hint. The "H3DWindowNode" is the third party API and has absolutely no relation to Qt so far. So you are suggestion the "has-a" relationship than "is-a" one. Now i have pulled out the documentation of the H3DWindowNode and it says that :



The base class for all window nodes.

A H3DWindowNode handles creation of windows and window properties for looking into a Scene. To implement a new window class the following functions have to be specified: swapBuffers(), initWindow(), initWindowHandler(), setFullscreen( bool fullscreen ) makeWindowActive(), setCursorType( const std::string & cursor_mode ) and getCursorForMode. For example implementation see GLUTWindow.

The GLUTwindow is an example which subclass the H3DWindowNode.


In that case, does the API give us the option to compose rather than inherit ?, do you see it ?


If if e try to compose how would we do this, for example



MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{

//i need to set to set the central widget and i want to have the H3DWindowNode to be the central widget
//can we make it the central widget unless we derive another class both from H3DWindowNode and QWidet
}




I think more suggestion over this thread.


Thanks so far

Regards
Sajjad

wysota
13th March 2012, 09:12
Maybe we started with asking the wrong question. So let's start from scratch --- what is the base class of H3DWindowNode and where does the class come from?

ChrisW67
13th March 2012, 09:27
It comes from an API called H3D (http://www.h3dapi.org/). It appears to be a "widget" itself but I haven't read too much of the documentation.

sajis997
13th March 2012, 10:15
Hi

H3DWindowNode is the base class for all window nodes. Please check the following link:

http://www.h3dapi.org/uploads/api/H3DAPI_2.1/docs/H3DAPI/html/classH3D_1_1H3DWindowNode.html


I really need some good design suggestion for this successful port from wxwidget to Qt.

I need to have this class or its subclass as the central widget of the main window. Please the corresponding UML diagram in the previous post. The diagram shows how it has been implemented in WxWidget.

I was suggested initially to have composition instead of inheritance . But i could not figure out how would it be possible with this third party API , specially once when you have to have this 3rd party class included as central widget into the main window.

I may be looking at the from the wrong point. The WxWidget have set the subclass of H3DWindowNode as a central window implicitly.


I shall be looking forward to more on this.


Regards
Sajjad

wysota
13th March 2012, 10:34
Both composition and inheritance are ok here as long as you remove ambiguities from your code. Hence with inheritance instead of saying "width" you have to write "H3DWindowNode::width", etc.

sajis997
13th March 2012, 11:00
Hi

I have subclassed from both H3DWindowNode and QWidget. The first one is because of we have to and the second one is because i wanted to have the subclass set as central widget of the main window. Now Both the class has the width and height parameter and i guess i need to be specific when it comes to changing any of its parameter. In the main window header file i have declared a reference pointer as follows:




//reference to the subclass of the H3DWindowNode
//please do not confuse with the glcanvas
MyH3DCanvasWindow *m_glWindow;





And MyH3DCanvaWindow has the following structure:



class MyH3DCanvasWindow : public H3D::H3DWindowNode, public QWidget
{
.....................
.....................
.....................
};



And i want to access the width and height parameter of one of the superclasses - in this case H3DWindowNode. I tried it as follows:




int w = sizeHint().width();
int h = sizeHint().height();

//set width and height of the glwindow

m_glWindow->width->setValue(w);// the width is specific to H3DWindowNode - Should we put the suggested scope resolution operator before width
m_glWindow->height->setValue(h);




I tried as follows and it compiles fine , but i do not get the aspect of it. Any explanation ?



m_glWindow->H3DWindowNode::width->setValue(w);
m_glWindow->H3DWindowNode::height->setValue(h);



Thanks a lot folks for being with me



Regards
Sajjad

wysota
13th March 2012, 11:10
There is QWidget::width and H3DWindowNode::width thus you have to tell the compiler which one you mean. Thus the latter works and the former doesn't.

By the way, inherit from QWidget first and then from H3D::H3DWindowNode. moc is picky about the inheritance order so if you decide to add signals or slots to your class, you'll have problems with wrong ordering.