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&) = delete;
OpenGLWidget& operator=(const OpenGLWidget&) = delete;
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:

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 qbuttongroup 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:
Assign a layout to the QOpenGLWidget
(e.g. QGridLayout
as I did in my sample).
Add QPushButton
s to this layout.
Btw. IMHO this is no specific problem about the QOpenGLWidget
– it should've happend with any other QWidget
as well.