Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make Qt Widget fill parent Widget?

I'm new to Qt programming. I'd like to create a simple app that can show an OpenGL model and provide some simple UI controls for manipulating it.

So far I've created my own GlWidget which subclasses QGLWidget and used Qt Designer to create a simple form. Within my main form, I've added a few UI elements and an empty QWidget that defines the region that I want my GlWidget to fill (I come from a Java background, and this is the way things are done in Java). I've also created an instance of my GlWidged and added it to this empty widget. The GlWidget even renders properly! The only problem is that it is postage-stamp sized and I can't figure out how to make it fill its entire parent widget.

How do I fix this?

MainForm.h

#ifndef _MAINFORM_H
#define _MAINFORM_H

#include "ui_MainForm.h"
#include "GlWidget.h"

class MainForm : public QMainWindow
{
    Q_OBJECT
public:
    MainForm();
    virtual ~MainForm();
private:
    Ui::MainForm widget;
    GlWidget* glWidget;
};

#endif  /* _MAINFORM_H */

MainForm.cpp

#include "MainForm.h"

MainForm::MainForm()
{
    widget.setupUi(this);

    glWidget = new GlWidget(widget.widget_gl);
}

MainForm::~MainForm()
{
}

GlWidget.h

#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <qtimer.h>
#include <Qt/qgl.h>

class GlWidget : QGLWidget
{
    Q_OBJECT

public:
    GlWidget(QWidget* parent = 0);

protected:
    virtual void initializeGL();
    virtual void resizeGL(int width, int height);
    virtual void paintGL();

    virtual void keyPressEvent(QKeyEvent *e);

    virtual void timeOut();

protected slots:
    virtual void timeOutSlot();

private:
    QTimer *m_timer;
};

#endif  /* GLWIDGET_H */

GlWidget.cpp

#include "GlWidget.h"

#include <qapplication.h>
#include <qtimer.h>
#include <qevent.h>

GlWidget::GlWidget(QWidget* parent)
: QGLWidget(parent)
{
    //setLayout();
    //showMaximized();

    int timerInterval = 1;

    if (timerInterval == 0)
    {
        m_timer = 0;
    } else
    {
        m_timer = new QTimer(this);
        connect(m_timer, SIGNAL(timeout()), this, SLOT(timeOutSlot()));
        m_timer->start(timerInterval);
    }
}

void GlWidget::keyPressEvent(QKeyEvent *e)
{
    switch (e->key())
    {
        case Qt::Key_Escape:
            close();
    }
}

void GlWidget::timeOut()
{
}

void GlWidget::timeOutSlot()
{
    timeOut();
}

void GlWidget::initializeGL()
{
    glShadeModel(GL_SMOOTH);

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClearDepth(1.0f);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}

void GlWidget::resizeGL(int width, int height)
{
    height = height ? height : 1;

    glViewport(0, 0, (GLint) width, (GLint) height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, (GLfloat) width / (GLfloat) height, 0.1f, 100.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void GlWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(-1.5f, 0.0f, -6.0f);

    glBegin(GL_TRIANGLES);
    glVertex3f(0.0f, 1.0f, 0.0f);
    glVertex3f(-1.0f, -1.0f, 0.0f);
    glVertex3f(1.0f, -1.0f, 0.0f);
    glEnd();

    glTranslatef(3.0f, 0.0f, 0.0f);

    glBegin(GL_QUADS);
    glVertex3f(-1.0f, 1.0f, 0.0f);
    glVertex3f(1.0f, 1.0f, 0.0f);
    glVertex3f(1.0f, -1.0f, 0.0f);
    glVertex3f(-1.0f, -1.0f, 0.0f);
    glEnd();
}
like image 716
kitfox Avatar asked Oct 08 '22 22:10

kitfox


1 Answers

You need to set layout for the main window and then add the QGLWidget to the layout. For example, your mainwindow.ui file could look as follows:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>478</width>
    <height>392</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QGLWidget" name="glView"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>478</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <customwidgets>
  <customwidget>
   <class>QGLWidget</class>
   <extends>QWidget</extends>
   <header>qglwidget.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

To add QGLWidget to the form, just add a QWidget to the form and then promote it to QGLWidget. For more information, see this question and the accepted answer of it.

like image 55
Smi Avatar answered Oct 12 '22 09:10

Smi