Important: Please read the Qt Code of Conduct -

[Solved] How to access an openGL widget globally?

  • Hey,

    In my application, I create a QGLWidget:

    @GLWidget::GLWidget() {
    //draw my openGL scene...

    And I have 2 other source files, one which actually displays the openGL widget, and another which creates some buttons to interact with it.

    dlg.cpp (creates UI with buttons to interact with the openGL widget)
    @extern GLWidget gl;
    connect(someButton, SIGNAL(clicked()), this, SLOT(myAction()));

    void dlg::myAction() {
    gl.someVariable = 1;

    mainwindow.cpp (puts a bunch of widgets together in a layout)
    @gl = new GLWidget();@

    The error I get is "undefined reference to 'gl' in dlg.cpp because I have not declared gl globally. My wish is to be able to write a declaration like
    @GLWidget gl;@

    as a global in mainwindow.cpp, but that is not allowed because then I get an error letting me know that I can't create a QPaintDevice before my QApplication.

    Any help with this would be must appreciated, I have answered many questions on this forum, but this is my first time posting a question of my own. Thanks.

  • Create it on the heap with operator new rather than on the stack. Then provide a pointer to your widget somewhere convenient, from your mainwindow say.

  • Thanks for your response. Now, in my mainwindow.cpp I have:
    @GLWidget *gl = new GLWidget();@
    in some function part of my mainwindow class. This function is what displays the widget, which works fine.

    In dlg.cpp I have: some function which connects a button click to a slot, and the slot should change values in the gl widget. i.e
    @gl.value = 1@

    Can you please show me what you mean by "Then provide a pointer to your widget somewhere convenient, from your mainwindow say." Thanks

  • You should keep a pointer to that widget a class that is central to your project, e.g. like ZapB said in your MainWindow. You have to either pass that pointer to any other class that should access that GLWidget or you implement a member function that returns the pointer to that GLWidget.

    In the latter case you have to pass a reference or pointer to the class that implements that function - and by using that pointer the "external" class may access functions of that GLWidget or connect signals to slots in that widget.

  • Thanks for the reply, can you provide any code snippet that demonstrates this? Still having some problems.

  • Keeping an object Globally is against OO Principles (wouldn't say it is hard and fast rule), but it is not suggested to do it that way, which has been carried out from C Paradigm.

    Would you consider of passing @GLWidget *gl = new GLWidget();@

    gl pointer to the other file may be through a method or may be passing an argument to the CTOR, while construction?

    If you still want to do it the way with Global Object, then the declaration of GLWidget *gl; should be outside the class in mainwindow.cpp and not within the class. If you declare it within the class, then gl pointer is only within the class and doesn't have the global definition.

  • I don't want to keep the widget global, I just want to access it from other source files. Even if I do declare it globally, I will get an error since you can't create a QPaintDevice before your QApplication.

    Can you elaborate on how I could do it through a method?

    Thanks for your reply

  • Presume then mainwindow.cpp has the below line @GLWidget *gl = new GLWidget();@

    If this gl isn't a member of mainwindow.cpp, I would suggest to make it as a member. You want to access this gl pointer within dlg.cpp. Presume mainwindow is created first and then dlg, isn't it? If so, gl would be created already.

    Would want to know how dlg is created? Is this dlg created from mainwindow.cpp? If you can pass, GLWidget *gl pointer as argument to constructor, then you can access gl pointer within dlg.cpp.

    Hope you understand the suggestion.

    If not, please send the code snippet, if not the whole logic, just the sketch/structure how your members are arranged and created, would be suffice.

  • If you have a look at my lecture here It has an example at the end using OpenGL, I also have many demo programs (does require my 3D library as well) here each one uses Qt and a GLWidget and shows different ways of accessing the GL Widget (message passing, signals and slots etc)

    There is also stuff on my blog. Hope this helps.

  • Please refer to my code snippets below for an example of my approach. Mind that these are just to point out how it works - they are far from complete and just some kinde of pseudocode.

    class MainWindow : public QMainWindow
    GLWidget* glWidget();
    GLWidget _glWidget;
    SomeOtherWidget _soWidget; // this will access _glWidget

    // constructor
    MainWindow::MainWindow(...) :
    _soWidget(this) // pass a pointer to the MainWindow to the widget that accesses _glWidget

    // this function is used to access the GLWidget
    GLWidget* MainWindow::glWidget()
    return &_glWidget;

    #include "mainwindow.h"

    class SomeOtherWidget : public QWidget
    SomeOtherWidget(MainWindow* parent);
    void paintSomething();

    void SomeOtherWidget::paintSomething()
    GLWidget* _glWidget = parent->glWidget();

    in SomeOtherWidget::paintSomething() you'll have to call the glWidget() function of the MainWindow class to get a pointer to the GLWidget you want to access.

  • Thanks for the help everyone! I made a global declaration in mainwindow: @GLWidget* glWidget;@

    then accessed it in my other dlg files using @extern GLWidget* glWidget;@

    and statements like

    @glWidget->somevariable = 1;@

    This is the result I wanted, thanks again for you help. Teamwork makes the dream work.

Log in to reply