Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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?


  • Lifetime Qt Champion

    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



  • @mrjj

    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'.


  • Lifetime Qt Champion

    @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!


  • Lifetime Qt Champion

    @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.


  • Lifetime Qt Champion

    @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) {}


  • Lifetime Qt Champion

    @stevereine
    The : QOpenGLWidget(parent) should go to .cpp
    as it dont like it in .h

    so .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?


  • Lifetime Qt Champion

    @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!


Log in to reply