Reputation: 21
So In my Qt app I have a class that inherit the QWindow class , and I would like it to be added to a QMainWindow so I tried using QWidget::createWindowContainer. I got a result I didn't expected when I set it as the centralWidget there are two windows instead of one I would like to know why.
The code of my QWindow class :
#include "common.hpp"
#include <QGuiApplication>
#include <QMouseEvent>
#include <QWheelEvent>
#include <vts-browser/log.hpp>
#include <vts-browser/map.hpp>
#include <vts-browser/mapOptions.hpp>
#include <vts-browser/camera.hpp>
#include <vts-browser/navigation.hpp>
#include <vts-renderer/renderer.hpp>
#include <stdexcept>
#include <QDebug>
static Gl *openglFunctionPointerInstance;
void *openglFunctionPointerProc(const char *name)
{
return (void*)openglFunctionPointerInstance->getProcAddress(name);
}
Gl::Gl(QSurface *surface) : surface(surface)
{}
void Gl::current(bool bind)
{
if (bind)
makeCurrent(surface);
else
doneCurrent();
}
void Gl::initialize()
{
setFormat(surface->format());
create();
if (!isValid())
throw std::runtime_error("unable to create opengl context");
}
void DataThread::run()
{
vts::setLogThreadName("data");
gl->current();
vts::renderer::installGlDebugCallback();
map->dataAllRun();
}
VtsWindow::VtsWindow()
{
QSurfaceFormat format;
format.setVersion(3, 3);
format.setProfile(QSurfaceFormat::CoreProfile);
#ifndef NDEBUG
format.setOption(QSurfaceFormat::DebugContext);
#endif
format.setDepthBufferSize(0);
format.setStencilBufferSize(0);
setFormat(format);
setSurfaceType(QWindow::OpenGLSurface);
resize(QSize(800, 600));
show();
dataThread.gl = std::make_shared<Gl>(this);
dataThread.gl->initialize();
dataThread.gl->current(false);
gl = std::make_shared<Gl>(this);
gl->setShareContext(dataThread.gl.get());
gl->initialize();
gl->current();
openglFunctionPointerInstance = gl.get();
vts::renderer::loadGlFunctions(&openglFunctionPointerProc);
vts::MapCreateOptions mapopts;
mapopts.clientId = "vts-browser-qt";
map = dataThread.map = std::make_shared<vts::Map>(mapopts);
map->setMapconfigPath(
"http://192.168.4.104:9000/store/vts/gebco_global/mapConfig.json",
"");
camera = map->createCamera();
navigation = camera->createNavigation();
context = std::make_shared<vts::renderer::RenderContext>();
context->bindLoadFunctions(map.get());
view = context->createView(camera.get());
dataThread.gl->moveToThread(&dataThread);
dataThread.start();
lastTime = std::chrono::high_resolution_clock::now();
requestUpdate();
hide();
}
VtsWindow::~VtsWindow()
{
view.reset();
navigation.reset();
camera.reset();
if (map)
map->renderFinalize();
dataThread.wait();
}
void VtsWindow::mouseMove(QMouseEvent *event)
{
QPoint diff = event->globalPos() - lastMousePosition;
lastMousePosition = event->globalPos();
double n[3] = { (double)diff.x(), (double)diff.y(), 0 };
if (event->buttons() & Qt::LeftButton)
navigation->pan(n);
if ((event->buttons() & Qt::RightButton)
|| (event->buttons() & Qt::MiddleButton))
navigation->rotate(n);
}
void VtsWindow::mousePress(QMouseEvent *)
{}
void VtsWindow::mouseRelease(QMouseEvent *)
{}
void VtsWindow::mouseWheel(QWheelEvent *event)
{
navigation->zoom(event->angleDelta().y() / 120.0);
}
bool VtsWindow::event(QEvent *event)
{
switch (event->type())
{
case QEvent::UpdateRequest:
tick();
return true;
case QEvent::MouseMove:
mouseMove(dynamic_cast<QMouseEvent*>(event));
return true;
case QEvent::MouseButtonPress:
mousePress(dynamic_cast<QMouseEvent*>(event));
return true;
case QEvent::MouseButtonRelease:
mouseRelease(dynamic_cast<QMouseEvent*>(event));
return true;
case QEvent::Wheel:
mouseWheel(dynamic_cast<QWheelEvent*>(event));
return true;
default:
return QWindow::event(event);
}
}
void VtsWindow::tick()
{
auto currentTime = std::chrono::high_resolution_clock::now();
double elapsedTime = std::chrono::duration_cast<std::chrono::microseconds>(
currentTime - lastTime).count() * 1e-6;
lastTime = currentTime;
requestUpdate();
if (!isExposed())
return;
if (!gl->isValid())
throw std::runtime_error("invalid gl context");
gl->makeCurrent(this);
QSize size = QWindow::size();
// release build -> catch exceptions and close the window
// debug build -> let the debugger handle the exceptions
#ifdef NDEBUG
try
{
#endif
map->renderUpdate(elapsedTime);
camera->setViewportSize(size.width(), size.height());
camera->renderUpdate();
view->options().targetFrameBuffer = gl->defaultFramebufferObject();
view->options().width = size.width();
view->options().height = size.height();
view->render();
#ifdef NDEBUG
}
catch(...)
{
this->close();
return;
}
#endif
// finish the frame
gl->swapBuffers(this);
}
and the code of my main :
#include <clocale>
#include <QApplication>
#include <QWindow>
#include <QtWidgets>
#include <QVBoxLayout>
#include "common.hpp"
#include "mainwindow.h"
//#include <vts-renderer/highPerformanceGpuHint.h>
int main(int argc, char *argv[])
{
QApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
QApplication app(argc, argv);
std::setlocale(LC_ALL, "C");
// Create the main window
MainWindow mainWindow;
QWidget *centralWidget = new QWidget(&mainWindow);
QVBoxLayout *layout = new QVBoxLayout(centralWidget);
VtsWindow vtsWindow;
QWidget *container = QWidget::createWindowContainer(&vtsWindow);
layout->addWidget(container);
mainWindow.setCentralWidget(centralWidget);
// Show the main window
mainWindow.show();
// run the main event loop
return app.exec();
}
Upvotes: 0
Views: 783
Reputation: 21
I found my answer, the show in the constructor was causing it. Instead of doing every initalization in the constructor I moved it to a function I call after the mainwindow is shown
Upvotes: 1