Qt isn't generating .h and .cpp files for QOpenGLWidget
-
I'll preface this by saying that I'm using the latest Windows 10, OpenGL 4.6.0, QT Creator 4.2.3, Qt 5.14.2.
I've been experimenting with OpenGL in QT, have had success with this creating OpenGL windows classes using either;
class OpenGLWindow : public QWindow, public QOpenGLFunctions
or
class myQOpenGLWindow : public QOpenGLWindow, protected QOpenGLFunctions
Now I'm trying to get this same code running, but using QOpenGLWidget. In QT, I've tried writing the code myself in Qt, in which case I just get a black screen, can't even update the color.
Now here is the crux of my question. I've also tried dragging and dropping the OpenGLWidget from the Qt toolbox onto the mainscreen in my Qt project in the IDE, then promoting that into a class of my own using QOpenGLWidget as the base class. It seems as if the end result should be a header and a source file from the new class I've created, yet I get nothing. In my main.cpp class, there is an #include mynewclass.h line now, but I get a compiler error that tells me that mynewclass.h can't be found, it wasn't generated.
Can someone explain to me what I could be doing wrong, so that I can generate the source and header files?
I've also tried Add-New C++ class, using QOPenGLWidget as the base class, but it only give me the barest skeleton code for the header and source files, basically just a class definition, not even a constructor function, this doesn't really help me. I'm making the assumption that if I am successful at this, that the IDE will generate some level of skeleton code that helps with initialization of the class. Am I wrong in my assumption?
-
Hi
Promoting does not generate anything. It's a way to use a custom widget in
Design mode.
You must supply the .cpp and .h of this custom widget your self.For QOpenGLWidget
Normally you inherit it and supply
void initializeGL()
void resizeGL(int w, int h)
void paintGL()Did you try the example in the docs ?
https://doc.qt.io/qt-5/qopenglwidget.html#details -
Thank you for the quick response! When I do the promotion, I see that it calls out a .h and a .cpp file to match my class name. To me that implies that it was generating these files, not just telling me what the file names should be. Thank you for your explanation. I thought that I did see somewhere where you could generate these files from the .ui file.
I have gone through that example code. Among many issues that I have found with it (I needed to add #include files, some of the variables, such as m_projection aren't even defined) it seems that the definition and the implementation of the constructor for MyGLWidget don't match. I get an error that says "out-of-line definition of 'MyGLWidget' does not match any declaration in 'MyGLWidget' ". Also, I believe the line in the main function should read 'MyGLWidget widget', not MyWidget widget'.
-
@stevereine
Hi
The promotion dialog asked what Class to "promote to" and in which .h file it can find that class. But i can see if you are not sure what that features does it could look like it asked what to call it and where to put it :)Yes you are right the class is called MyGLWidget so main.cpp is wrong. Good catch.
Did you fix the constructor error ?
-
I have not been able to solve the constructor problem. I'll be honest with you, I'm a decent C++ guy but some of the nomenclature I see around contructors does confuse me. There might be something very obvious here that I don't understand. Here is the definition and the implementation. I didn't change anything, just cut and pasted from the example code.
definition:
public:
MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) { }implementation:
MyGLWidget::MyGLWidget()
: m_program(0), m_shader(0), m_texture(0)
{
// No OpenGL resource initialization is done here.
}The brackets at the end of the implementation don't look right to me. I did try removing them, but just got different error.
thank you again!
-
@stevereine
It seems you have 2 constructors
one that is fully defined in .h
the
MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) { }And then in .cpp you have another one that has no definition in .h and i think thats
what the "out of bounds " was talking about.what about just doing
MyGLWidget(QWidget *parent) : m_program(0), m_shader(0), m_texture(0), QOpenGLWidget(parent) { }and get rid of
MyGLWidget::MyGLWidget()
: m_program(0), m_shader(0), m_texture(0)
{
// No OpenGL resource initialization is done here.
}as that takes no parent which we want for a QWidget so we would not use this anyway.
update:
maybe do it right so its
.h
MyGLWidget(QWidget *parent);
and .cpp
MyGLWidget::MyGLWidget(QWidget *parent) : m_program(0), m_shader(0), m_texture(0), QOpenGLWidget(parent) { } -
I'm one step ahead of you. I did try this earlier. When I comment out what you suggest, I get the following errors;
definition of implicitly declared destructor
no matching constructor for initialization of 'MyGLWidget'
MyGLWidget: no appropriate default constructor available
To fix at least part of this, I tried commenting out the destructor. Note I'm pasting the destructor from the example code here as well.
MyGLWidget::~MyGLWidget()
{
// Make sure the context is current and then explicitly
// destroy all underlying OpenGL resources.
makeCurrent();delete m_texture; delete m_shader; delete m_program; m_vbo.destroy(); m_vao.destroy(); doneCurrent();
}
When I comment out the destructor, I am left with two errors. I think it's really one error, both related to the constructor. Here are the errors:
error: no matching constructor for initialization of 'MyGLWidget'
error: C2512: 'MyGLWidget': no appropriate default constructor available
Regardless, I think we are close to solving this.
-
@stevereine
Hi
"MyGLWidget: no appropriate default constructor available"
Sounds to me like you create one without giving it a parent?
like
MyGLWidget widget;
so fix is to do
MyGLWidget widget(nullptr);
(not giving it a parent will make it a window but i guess that is fine)
I assume its still the same main as in example ? -
One more comment, it doesn't seem like it's recognizing that line of code as a constructor:
public:
MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) {} -
@stevereine
The : QOpenGLWidget(parent) should go to .cpp
as it dont like it in .hso .h
MyGLWidget(QWidget *parent);
and in cpp
MyGLWidget::MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) {}
-
Yes! That worked. It makes sense, but I never would have figured out by myself. I can now initialize the background to whichever color I want.
I've moved on now to adding the shaders and the init code for the shaders, getting an assert error when using;
attributeLocation("posAttr");m_posAttr = m_program->attributeLocation("posAttr");
The problem that I started this thread with is solved. Should I start a new query for this new assert error?
-
@stevereine
Hi
Well i also forgot it has to be .cpp for the ctor initialiser list. 😋I would make this as solved and open a new one for the shader issue simply
to make sure people see the actually issue right away. -
will do, thank you!