1

I am designing a user interface with Qt Creator. I have a openGLwidget which covers all the form and I want to place some buttons aligned to bottom and some kind of notification frames over the widget. Is there any default way to do that?

When I try to design that on creator, I could not get rid of layout limits and don't allow me to place a widget over openglwidget.

eyllanesc
  • 190,383
  • 15
  • 87
  • 142
meakcey
  • 63
  • 10

1 Answers1

1

When reading the question first, I was reading this as “How to make a QOpenGLWidget with Head-Up Display with buttons?”.

How to make a QOpenGLWidget with Head-Up Display (painted with QPainter), I once answered in SO: Paint a rect on qglwidget at specifit times. However, there was only painting – no interactive widgets.

Hence, I prepared a new sample testQGLWidgetHUDButtons.cc:

#include <QtWidgets>

class OpenGLWidget: public QOpenGLWidget, public QOpenGLFunctions {

  private:
    struct ClearColor {
      float r, g, b;
      ClearColor(): r(0.6f), g(0.8f), b(1.0f) { }
    } _clearColor;

  public:
    OpenGLWidget(QWidget *pQParent = nullptr):
      QOpenGLWidget(pQParent),
      QOpenGLFunctions()
    { }

    virtual ~OpenGLWidget() = default;

    OpenGLWidget(const OpenGLWidget&) = default;
    OpenGLWidget& operator=(const OpenGLWidget&) = default;

    void setClearColor(float r, float g, float b);

  protected:

    virtual void initializeGL() override;
    virtual void paintGL() override;

};

void OpenGLWidget::setClearColor(float r, float g, float b)
{
  _clearColor.r = r; _clearColor.g = g; _clearColor.b = b;
  update(); // force update of widget
}

void OpenGLWidget::initializeGL()
{
  initializeOpenGLFunctions();
}

void OpenGLWidget::paintGL()
{
  glClearColor(
    _clearColor.r, _clearColor.g, _clearColor.b, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  OpenGLWidget qWin;
  QGridLayout qGrid;
  QPushButton qBtn1(QString::fromUtf8("Black BG"));
  qGrid.addWidget(&qBtn1, 1, 1);
  QPushButton qBtn2(QString::fromUtf8("White BG"));
  qGrid.addWidget(&qBtn2, 1, 2);
  QPushButton qBtn3(QString::fromUtf8("Blue BG"));
  qGrid.addWidget(&qBtn3, 1, 3);
  qGrid.setRowStretch(0, 1);
  qGrid.setColumnStretch(0, 1);
  qWin.setLayout(&qGrid);
  qWin.show();
  // install signal handlers
  QObject::connect(&qBtn1, &QPushButton::clicked,
    [&qWin](bool) { qWin.setClearColor(0.0f, 0.0f, 0.0f); });
  QObject::connect(&qBtn2, &QPushButton::clicked,
    [&qWin](bool) { qWin.setClearColor(1.0f, 1.0f, 1.0f); });
  QObject::connect(&qBtn3, &QPushButton::clicked,
    [&qWin](bool) { qWin.setClearColor(0.6f, 0.8f, 1.0f); });
  // runtime loop
  return app.exec();
}

and the project file testQGLWidgetHUDButtons.pro:

SOURCES = testQGLWidgetHUDButtons.cc

QT += widgets opengl

Compiled and tested in VS2013 on Windows 10:

Snapshot of testQGLWidgetHUDButtons in Windows 10

It's actually quite easy – QOpenGLWidget is derived from QWidget. QWidget provides the method QWidget::setLayout(). To add child widgets, a QLayout should be used which manages layout of children in parent widget (and takes part in size negotiation when parent widget is layouted).

To keep it simple, I used a QGridLayout where buttons are placed in cells (1, 1), (1, 2), and (1, 3). Row 0 and column 0 are left empty but enabled for stetching. This results effectively in attaching the buttons in lower right corner.


When I was about to publish this answer, I took a second look onto the question and realized the Qt Button Group in title. I would've ignore it (multiple buttons are a button group?) but there is also the which made me stumbling.

A QButtonGroup:

The QButtonGroup class provides a container to organize groups of button widgets.

QButtonGroup provides an abstract container into which button widgets can be placed. It does not provide a visual representation of this container (see QGroupBox for a container widget), but instead manages the states of each of the buttons in the group.

(Emphasize mine.)

So, a button group can be used e.g. to keep radio buttons in sync. It is derived from QObject and hence, neither a QWidget nor a QLayout. Thus, it's not suitable to add visible child widgets to the QOpenGLWidget.

Though I've no experiences with QCreator, I assume it should work there as well as it does in my sample:

  1. Assign a layout to the QOpenGLWidget (e.g. QGridLayout as I did in my sample).

  2. Add QPushButtons to this layout.

Btw. IMHO this is no specific problem about the QOpenGLWidget – it should've happend with any other QWidget as well.

Scheff's Cat
  • 16,517
  • 5
  • 25
  • 45