Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QGLWidget within a QAbstractScrollArea
Forum Updated to NodeBB v4.3 + New Features

QGLWidget within a QAbstractScrollArea

Scheduled Pinned Locked Moved General and Desktop
14 Posts 3 Posters 8.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Z Offline
    Z Offline
    ZapB
    wrote on last edited by
    #2

    Can you not just use QScrollArea and QScrollArea::setWidget()? Something like:

    @
    QScrollArea* scroll = new QScrollArea( this );
    QGLWidget* glWidget = new QGLWidget;
    scroll->setWidget( glWidget );
    @

    Not tested, but I think it should work. You may need to set a size for your QGLWidget.

    Edit: Fixed typo. s/QScrollWidget/QScrollArea/

    Nokia Certified Qt Specialist
    Interested in hearing about Qt related work

    1 Reply Last reply
    0
    • K Offline
      K Offline
      Kono
      wrote on last edited by
      #3

      [quote author="ZapB" date="1301599554"]Can you not just use QScrollArea and QScrollArea::setWidget()? Something like:

      @
      QScrollWidget* scroll = new QScrollWidget( this );
      QGLWidget* glWidget = new QGLWidget;
      scroll->setWidget( glWidget );
      @

      Not tested, but I think it should work. You may need to set a size for your QGLWidget.[/quote]
      What's a QScrollWidget? I don't have it, I'm using Qt 4.7.

      1 Reply Last reply
      0
      • Z Offline
        Z Offline
        ZapB
        wrote on last edited by
        #4

        Oopsy sorry, I meant QScrollArea not QScrollWidget. The text was right the code was wrong.

        Nokia Certified Qt Specialist
        Interested in hearing about Qt related work

        1 Reply Last reply
        0
        • K Offline
          K Offline
          Kono
          wrote on last edited by
          #5

          I tried doing that.
          It still doesn't render.

          I think I really do need to inherit QAbstractScrollArea.

          Any more suggestions?

          1 Reply Last reply
          0
          • Z Offline
            Z Offline
            ZapB
            wrote on last edited by
            #6

            It works for me (tm). Here is an example showing it in action.

            Create a new Qt C++ application using qt-creator and choose QMainWindow as the base class for the main window in the wizard.

            Then in design mode, add a QScrollArea to the main window and lay it out vertically. I also changed the name of the scroll area to m_scrollArea (as you'll see in the code below).

            Now edit the project so that it looks like this:

            mainwindow.h : no changes needed.

            mainwindow.cpp:

            @
            #include "mainwindow.h"
            #include "ui_mainwindow.h"

            #include "solarsystem.h"

            MainWindow::MainWindow( QWidget* parent )
            : QMainWindow( parent ),
            ui( new Ui::MainWindow )
            {
            ui->setupUi( this );
            SolarSystem* solar = new SolarSystem;
            solar->setMinimumSize( 1024, 768 );
            ui->m_scrollArea->setWidget( solar );
            }

            MainWindow::~MainWindow()
            {
            delete ui;
            }
            @

            All I do is create a SolarSystem widget (which is derived from QGLWidget - source below). This just gives us something to look at ;-)

            main.cpp:

            @
            #include <QtGui/QApplication>
            #include "mainwindow.h"

            #include <GL/glut.h>

            int main(int argc, char *argv[])
            {
            QApplication a(argc, argv);
            glutInit( &argc, argv );
            MainWindow w;
            w.show();

            return a.exec&#40;&#41;;
            

            }
            @

            For completeness here is my SolarSystem class (ported from one of the examples in the OpenGL superbible book):

            solarsystem.h:

            @
            #ifndef SOLARSYSTEM_H
            #define SOLARSYSTEM_H

            #include <QGLWidget>

            class SolarSystem : public QGLWidget
            {
            Q_OBJECT
            public:
            SolarSystem( QWidget* parent = 0 );

            public slots:
            void advance();

            protected:
            virtual void initializeGL();
            virtual void resizeGL( int w, int h );
            virtual void paintGL();

            virtual void keyPressEvent( QKeyEvent* e );
            

            private:
            float m_thetaEarth;
            float m_thetaMoon;
            };

            #endif // SOLARSYSTEM_H
            @

            solarsystem.cpp:

            @
            #include "solarsystem.h"

            #include <QApplication>
            #include <QKeyEvent>
            #include <QTimer>
            #include <QVector3D>

            #include <GL/glut.h>

            SolarSystem::SolarSystem( QWidget* parent )
            : QGLWidget( parent ),
            m_thetaEarth( 0.0f ),
            m_thetaMoon( 0.0f )
            {
            QTimer* timer = new QTimer( this );
            connect( timer, SIGNAL( timeout() ), SLOT( advance() ) );
            timer->start( 1000 / 60 );
            }

            void SolarSystem::advance()
            {
            m_thetaEarth += 0.25f;
            if ( m_thetaEarth > 360.0f )
            m_thetaEarth -= 360.0f;

            m_thetaMoon += 2.0f;
            if ( m_thetaMoon > 360.0f )
                m_thetaMoon -= 360.0f;
            
            updateGL();
            

            }

            void SolarSystem::initializeGL()
            {
            // Set the clear color to black
            glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

            // Enable depth testing
            glEnable( GL_DEPTH_TEST );
            
            // Enable back face culling
            glFrontFace( GL_CCW ); // Counter clock-wise polygons face out
            glEnable( GL_CULL_FACE );
            
            // Enable lighting
            const float whiteLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
            const float sourceLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
            glEnable(GL_LIGHTING);
            
            // Setup and enable light 0
            glLightModelfv( GL_LIGHT_MODEL_AMBIENT, whiteLight );
            glLightfv( GL_LIGHT0, GL_DIFFUSE, sourceLight );
            glEnable( GL_LIGHT0 );
            
            // Enable color tracking
            glEnable( GL_COLOR_MATERIAL );
            
            // Set Material properties to follow glColor values
            glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
            

            }

            void SolarSystem::resizeGL( int w, int h )
            {
            // Prevent a divde by zero
            if ( h == 0 )
            h = 1;

            // Set the viewport to window dimensions
            glViewport( 0, 0, w, h );
            
            // reset the coordinate system
            glMatrixMode( GL_PROJECTION );
            glLoadIdentity();
            
            // Establish the clipping volume by setting up an orthographic projection
            double aspectRatio = double( w ) / double( h );
            double verticalViewingAngle = 45.0;
            gluPerspective( verticalViewingAngle, aspectRatio, 1.0, 425.0 );
            
            glMatrixMode( GL_MODELVIEW );
            glLoadIdentity();
            

            }

            void SolarSystem::paintGL()
            {
            // Clear the buffer with the current clearing color
            glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

            // Set the identity modelview transform
            glMatrixMode( GL_MODELVIEW );
            glPushMatrix();
            
            // Translate the whole scene a little
            glTranslatef( 0.0f, 0.0f, -300.0f );
            
            // Set drawing colour to yellow and draw the Sun
            glColor3f( 1.0f, 1.0f, 0.0f );
            glDisable( GL_LIGHTING );
            glutSolidSphere( 15.0f, 30, 17 );
            glEnable( GL_LIGHTING );
            
            // Position a light to simulate the Sun as a light source
            const float lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };
            glLightfv( GL_LIGHT0, GL_POSITION, lightPos );
            
            // Draw the Earth
            glColor3f( 0.0f, 0.0f, 1.0f );
            glRotatef( m_thetaEarth, 0.0f, 1.0f, 0.0f );
            glTranslatef( 105.0f, 0.0f, 0.0f );
            glutSolidSphere( 15.0f, 30, 17 );
            
            // Rotate from Earth based coords and draw the moon
            glColor3f( 0.7f, 0.7f, 0.7f );
            glRotatef( m_thetaMoon, 0.0f, 1.0f, 0.0f );
            glTranslatef( 30.0f, 0.0f, 0.0f );
            glutSolidSphere( 6.0f, 15, 15 );
            
            glPopMatrix();
            

            }

            void SolarSystem::keyPressEvent( QKeyEvent* e )
            {
            switch ( e->key() )
            {
            case Qt::Key_Escape:
            QCoreApplication::instance()->quit();
            break;

                default:
                    QGLWidget::keyPressEvent( e );
            }
            

            }
            @

            Anyway, the above all runs and works as expected. I see scroll bars when the mainwindow and scroll area are too small to accomodate the minimum size of the SolarSystem widget.

            Nokia Certified Qt Specialist
            Interested in hearing about Qt related work

            1 Reply Last reply
            0
            • K Offline
              K Offline
              Kono
              wrote on last edited by
              #7

              Apparently I needed to set the minimum size.

              It works and all but I need control over the scrollbars..
              So I've to use the QAbstractScrollArea anyway.

              MapView.h (QAbstractScrollArea class decleration):

              @#ifndef MAPVIEW_H
              #define MAPVIEW_H

              #include <QAbstractScrollArea>

              class Map;
              class MapRenderer;

              class MapView : public QAbstractScrollArea
              {
              Q_OBJECT
              public:
              explicit MapView(QWidget *parent = 0);

              void setMap(Map *map);
              

              private:
              Map* mMap;
              MapRenderer *mMapRenderer;
              };

              #endif // MAPVIEW_H
              @

              MapView.cpp (QAbstractScrollArea class implementation):
              @#include "mapview.h"
              #include "map.h"
              #include "maprenderer.h"

              #include <QScrollBar>

              MapView::MapView(QWidget *parent) :
              QAbstractScrollArea(parent),
              mMap(0),
              mMapRenderer(0)
              {
              setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
              setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
              }

              void MapView::setMap(Map *map)
              {
              mMap = map;
              mMapRenderer = new MapRenderer(map);

              setViewport(mMapRenderer);
              

              }
              @

              MapRenderer.cpp (QGLWidget subclass implementation):
              @#include "maprenderer.h"

              MapRenderer::MapRenderer(Map *map, QWidget *parent) :
              QGLWidget(parent),
              mMap(map)
              {
              }

              void MapRenderer::initializeGL()
              {
              glViewport(0, 0, width(), height());

              glEnable(GL_DEPTH_TEST);
              glEnable(GL_TEXTURE_2D);
              
              glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
              
              glMatrixMode(GL_PROJECTION);
              glLoadIdentity();
              gluPerspective(45.0, 320.0 / 240.0, 0.001, 100);
              
              glMatrixMode(GL_MODELVIEW);
              glLoadIdentity();
              gluLookAt(0.0, 20.0, 10.0,
                        0.0, 0.0, 0.0,
                        0.0, 1.0, 0.0);
              

              }

              void MapRenderer::resizeGL(int w, int h)
              {
              glViewport(0, 0, w, h);
              }

              void MapRenderer::paintGL()
              {
              glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
              }
              @

              This is how I use the MapView:
              @mMapView = new MapView();
              setCentralWidget(mMapView);@

              1 Reply Last reply
              0
              • Z Offline
                Z Offline
                ZapB
                wrote on last edited by
                #8

                Glad that you got it working. Good luck with the rest of your project.

                Nokia Certified Qt Specialist
                Interested in hearing about Qt related work

                1 Reply Last reply
                0
                • K Offline
                  K Offline
                  Kono
                  wrote on last edited by
                  #9

                  [quote author="ZapB" date="1301668583"]Glad that you got it working. Good luck with the rest of your project.[/quote]
                  It doesn't work..

                  1 Reply Last reply
                  0
                  • Z Offline
                    Z Offline
                    ZapB
                    wrote on last edited by
                    #10

                    Which aspect? The example I posted worked in that it embedded a QGLWidget into the scroll view. What else is missing?

                    Nokia Certified Qt Specialist
                    Interested in hearing about Qt related work

                    1 Reply Last reply
                    0
                    • K Offline
                      K Offline
                      Kono
                      wrote on last edited by
                      #11

                      I'm talking about my code. I said I needed help with inheriting QAbstractScrollArea not QScrollArea, that's because I need control over the scrollbars.
                      [quote author="ZapB" date="1302016156"]Which aspect? The example I posted worked in that it embedded a QGLWidget into the scroll view. What else is missing?[/quote]

                      1 Reply Last reply
                      0
                      • Z Offline
                        Z Offline
                        ZapB
                        wrote on last edited by
                        #12

                        But you have not said how it doesn't work or what you are trying to achieve. Simply saying that you want/need to use QAbstractScrollArea to control the scroll bars is not enough info. What does QScrollArea do with the scroll bars that is wrong in your case?

                        I am only trying to help but I need more information to do so.

                        Nokia Certified Qt Specialist
                        Interested in hearing about Qt related work

                        1 Reply Last reply
                        0
                        • K Offline
                          K Offline
                          Kono
                          wrote on last edited by
                          #13

                          [quote author="ZapB" date="1302016490"]But you have not said how it doesn't work or what you are trying to achieve. Simply saying that you want/need to use QAbstractScrollArea to control the scroll bars is not enough info. What does QScrollArea do with the scroll bars that is wrong in your case?

                          I am only trying to help but I need more information to do so.[/quote]
                          What doesn't work is that I don't see the graphics produced by the QGLWidget in my QAbstractScrollArea.
                          QGLWidget is set as its viewport.
                          I tried setting a breakpoint in the paintGL and it did reach it, so I guess the problem is in the QAbstractScrollArea.

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            mrhill
                            wrote on last edited by
                            #14

                            QAbstractScrollArea by default filters some events for its viewport widget, including the paint event (QPaintEvent / QEvent::Paint). You need to manually forward it from the derived QAbstractScrollArea to your QGLWidget.

                            One way to do this, is to override viewportEvent() in your MapView, and return false to indicate that the paint event should be propagated to the viewport(), i.e.:

                            @bool MapView ::viewportEvent(QEvent* e)
                            {
                            if (e->type() == QEvent::Paint)
                            return false;
                            return QAbstractScrollArea::viewportEvent(e);
                            }
                            @

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved