Can't link QOpenGLWidget into a Form
-
Hi guys, I have an application that uses QOpenGLWidget to show a scene.
Now, I want to add an interface to it so I created a Form and I added to it a QOpenGLWidget element:
Now I am trying to link the QOpenGLWidget I had created to this QOpenGlWidget that is into the Form but I cant. It shows a black screen.
This is the main class where I initialized the QOpenGLWidget:
int main(int argc, char *argv[]) { QApplication app(argc, argv); QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); format.setVersion(4, 1); format.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(format); glwindow *ventana = new glwindow(); ventana->setFormat(format); ventana->show(); std::cout<<"Ventana lanzada"<<std::endl; ventana->setMouseTracking(true); ventana->installEventFilter(ventana);
That shows me a window like this:
Now I added code to link this window to the frame I have created:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); format.setVersion(4, 1); format.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(format); glwindow *ventana = new glwindow(); ventana->setFormat(format); ventana->show(); std::cout<<"Ventana lanzada"<<std::endl; Form *ui = new Form(); ui->setQOpenGLWindow(ventana); ui->show(); ventana->setMouseTracking(true); ventana->installEventFilter(ventana);
and this is the result. On the left there is the form and on the right there is the window that I shown you before.
The black screen is a QOpenGLWidget that should show what is in the right window.
What is happening?
I leave here the form classes too:#ifndef FORM_H #define FORM_H #include <QWidget> #include "glwindow.h" namespace Ui { class Form; } class Form : public QWidget { Q_OBJECT public: explicit Form(QWidget *parent = nullptr); void setQOpenGLWindow(glwindow *window); ~Form(); private: Ui::Form *ui; }; #endif // FORM_H
#include "form.h" #include "ui_form.h" Form::Form(QWidget *parent) : QWidget(parent), ui(new Ui::Form) { ui->setupUi(this); } void Form::setQOpenGLWindow(glwindow *window) { ui->openGLWidget = window; } Form::~Form() { delete ui; }
-
Hi,
You are just replacing a pointer. That won't automagically replace the original widget by yours.
You should rather use the promote feature.
-
@SGaist ok now I added a promote to my class glwindow which is the QopenglWidget class and my app crashes.
It says :
This is my glwindow.cpp:#include "glwindow.h" glwindow::glwindow(QWidget *parent): QOpenGLWidget (parent) { } glwindow::~glwindow() { } void glwindow::initializeGL() { // Set up the rendering context, load shaders and other resources, etc.: initializeOpenGLFunctions(); printContextInformation(); glClearColor(0.5f, 0.5f, 0.5f, 1.0f); // - Le decimos a OpenGL que tenga en cuenta la profundidad a la hora de dibujar. // No tiene por qué ejecutarse en cada paso por el ciclo de eventos. glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); } void glwindow::paintGL() { // Draw the scene: glClear(GL_COLOR_BUFFER_BIT); renderer::getInstance()->dibujar(); } void glwindow::resizeGL(int w, int h) { renderer::getInstance()->redimensionarAreaDibujo(w,h); window_refresh(); } bool glwindow::eventFilter(QObject *obj, QEvent *event) { if (event->type() == QEvent::KeyPress) { QKeyEvent* keyEvent = static_cast<QKeyEvent*>(event); if(keyEvent->key()==Qt::Key_Escape) { this->close(); } if(keyEvent->key()==Qt::Key_P) { renderer::getInstance()->setModoDibujo(0); } if(keyEvent->key()==Qt::Key_W) { renderer::getInstance()->setModoDibujo(1); } if(keyEvent->key()==Qt::Key_T) { renderer::getInstance()->setModoDibujo(2); } if(keyEvent->key()==Qt::Key_A) { renderer::getInstance()->setModoDibujo(3); } if(keyEvent->key()==Qt::Key_Z) { renderer::getInstance()->setModoDibujo(4); } if(keyEvent->key()==Qt::Key_X) { renderer::getInstance()->setModoDibujo(5); } if(keyEvent->key()==Qt::Key_C) { renderer::getInstance()->setModoDibujo(6); } if(keyEvent->key()==Qt::Key_V) { renderer::getInstance()->setModoDibujo(7); } if(keyEvent->key()==Qt::Key_J) { renderer::getInstance()->setModoTextura(false); } if(keyEvent->key()==Qt::Key_K) { renderer::getInstance()->setModoTextura(true); } if(keyEvent->key()==Qt::Key_1) { renderer::getInstance()->camaraSiguiente(); } if(keyEvent->key()==Qt::Key_2) { renderer::getInstance()->camaraAnterior(); } if(keyEvent->key()==Qt::Key_N) { float posX, posY, posZ,lookX,lookY,lookZ,fovX; std::cout << "Proceso de creacion de una nueva camara virtual" << std::endl; std::cout << "Por favor, especifique su posicion en los ejes: " << std::endl; std::cout << "Eje X: "; std::cin >> posX; std::cout << std::endl; std::cout << "Eje Y: "; std::cout << std::endl; std::cin >> posY; std::cout << "Eje Z: "; std::cin >> posZ; std::cout << std::endl; std::cout << "Especifique hacia donde desea mirar: " << std::endl; std::cout << "Eje X: "; std::cin >> lookX; std::cout << std::endl; std::cout << "Eje Y: "; std::cin >> lookY; std::cout << std::endl; std::cout << "Eje Z: "; std::cin >> lookZ; std::cout << std::endl; std::cout << "Por ultimo especifique su angulo de vision: " << std::endl; std::cout << "Angulo de vision: "; std::cin >> fovX; renderer::getInstance()->crearCamara(QVector3D(posX, posY, posZ), QVector3D(lookX, lookY, lookZ), fovX); } if(keyEvent->key()==Qt::Key_Alt) { pan = true; } if(keyEvent->key()==Qt::Key_Control) { tilt=true; } if(keyEvent->key()==Qt::Key_Right) { renderer::getInstance()->moverCamara(TRUCK, 0.3f); } if(keyEvent->key()==Qt::Key_Left) { renderer::getInstance()->moverCamara(TRUCK, -0.3f); } if(keyEvent->key()==Qt::Key_Up) { renderer::getInstance()->moverCamara(CRANE, -0.3f); } if(keyEvent->key()==Qt::Key_Down) { renderer::getInstance()->moverCamara(BOOM, 0.3f); } if(keyEvent->key()==Qt::Key_F1) { renderer::getInstance()->moverCamara(DOLLY, -0.3f); } if(keyEvent->key()==Qt::Key_F2) { renderer::getInstance()->moverCamara(DOLLY, 0.3f); std::cout<<"Realizando DOLLY"<<std::endl; } window_refresh(); return true; } if (event->type() == QEvent::KeyRelease) { pan = false; tilt = false; window_refresh(); return true; } if(event->type() == QEvent::MouseButtonPress) { arrastrar = true; window_refresh(); return true; } if(event->type() == QEvent::MouseButtonRelease) { arrastrar = false; window_refresh(); return true; } if(event->type() == QEvent::Wheel) { QWheelEvent* wheelEvent = static_cast<QWheelEvent*>(event); if(wheelEvent->delta()> 0) { renderer::getInstance()->modificarZoom(-2); }else { renderer::getInstance()->modificarZoom(2); } window_refresh(); return true; } if(event->type() == QEvent::MouseMove) { QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); int xpos = mouseEvent->x(); int ypos = mouseEvent->y(); if (arrastrar) { if (pan) { renderer::getInstance()->moverCamara(PAN, (posX - xpos)/2); posX = xpos; posY = ypos; } else if (tilt) { renderer::getInstance()->moverCamara(TILT, (posY - ypos)/2); posX = xpos; posY = ypos; } else { renderer::getInstance()->moverCamara(ORBIT_HORIZONTAL, (xpos - posX)); renderer::getInstance()->moverCamara(ORBIT_VERTICAL, ((ypos - posY) / 2)); posX = xpos; posY = ypos; } } else { posX = xpos; posY = ypos; } window_refresh(); return true; } return QObject::eventFilter(obj, event); } void glwindow::window_refresh() { renderer::getInstance()->refreshCallback(); update(); } void glwindow::printContextInformation() { QString glType; QString glVersion; QString glProfile; // Get Version Information glType = (context()->isOpenGLES()) ? "OpenGL ES" : "OpenGL"; glVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION)); // Get Profile Information #define CASE(c) case QSurfaceFormat::c: glProfile = #c; break switch (format().profile()) { CASE(NoProfile); CASE(CoreProfile); CASE(CompatibilityProfile); } #undef CASE // qPrintable() will print our QString w/o quotes around it. qDebug() << qPrintable(glType) << qPrintable(glVersion) << "(" << qPrintable(glProfile) << ")"; }
and this is the code of the binding:
bool shaderProgram::use() { // Antes de activar un shader program para su uso, hay que comprobar // si se ha creado bien y se ha enlazado bien if ((handler) && (linked)) { shaderP->bind(); return true; } else { std::cout << "Cannot use shader program"; return false; } }
Without the promote added it works in a different window as you can see in my first post but now I think I have to d something with the context but I dont know what.
Thanks
-
In that case, let's take another way. Put a layout in your UI and add your OpenGL widget to it. This will likely be simpler in the short run.
-
@SGaist How an I add my OpenGLWIdget to the UI instead of adding an empty one?. I am adding the widgets from here:
It has to be something with the context, I was not using any function related with the context when I hadn't the UI but It seems that now I need to use it and I don't know how.
-
@JesusM said in Can't link QOpenGLWidget into a Form:
How an I add my OpenGLWIdget to the UI instead of adding an empty one?
@SGaist suggested to do it in your code manually (not using Designer).
-
@SGaist ok, It works but it creates the widget at the bottom:
and I need to have it on the left side, as I had it before creating it manually:
This is my hierarchy (with the empty QOpenGLWidget):
I added the widget to the centralWidget which has a grid layout. With the Qt Designer I just needed to drag my widget to the left margin to move it to the left but now I can't do it as I created the widget by code. -
@JesusM said in Can't link QOpenGLWidget into a Form:
I added the widget to the centralWidget
You should add it to the layout at desired position.
-
@jsulm I think I didn't explain myself well, sorry. The hierarchy that I posted is before I added the QOpenGLWidget by code, just to show you where I had it added. When I added it by code I removed that component from the Qt Designer so, now, my hierarchy in the Qt Designer hasn't got that component.
I added this code to the constructor of my UI to add the QOpenGLWidget:
QSurfaceFormat format; format.setDepthBufferSize(24); format.setStencilBufferSize(8); format.setVersion(4, 1); format.setProfile(QSurfaceFormat::CoreProfile); QSurfaceFormat::setDefaultFormat(format); glwindow *ventana = new glwindow(); ventana->setFormat(format); ventana->show(); ventana->setMouseTracking(true); ventana->installEventFilter(ventana); std::cout<<"Ventana lanzada"<<std::endl; ui->gridLayout->addWidget(ventana);
This code add the QOpenGLWidget but at the bottom of the grid layout.
-
@JesusM said in Can't link QOpenGLWidget into a Form:
ui->gridLayout->addWidget(ventana);
You don't specify where exactly you want this widget to be in the layout. Take a look at https://doc.qt.io/qt-5/qgridlayout.html#addWidget
-
@jsulm all the values I have tried make my program crash. I think I don't understand well how to use the addWidget function.
I tried all of this:ui->gridLayout->addWidget(ventana,0,0); // This doesn't crash but the widget is still at the bottom; ui->gridLayout->addWidget(ventana,1,0); //Same here //From here all make my program crash. ui->gridLayout->addWidget(ventana,0,1); ui->gridLayout->addWidget(ventana,1,1); ui->gridLayout->addWidget(ventana,0,0, Qt::AlignLeft); ui->gridLayout->addWidget(ventana,0,1, Qt::AlignLeft); ui->gridLayout->addWidget(ventana,1,0, Qt::AlignLeft); ui->gridLayout->addWidget(ventana,1,1, Qt::AlignLeft);
-
I found the solution. I had to set the QSizePolicy of my widget and then place the widget at the top-left side:
ventana->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Expanding); ui->gridLayout->addWidget(ventana,0,0);
Thanks all for helping :)