Revert "Allow for when a Scene3D item switches screens"

This reverts commit 648b7459e8.

Reason for revert: Introduces QTBUG-82275

Change-Id: I5514ad58707c086eaaab3203773614c939e461e8
Reviewed-by: Mike Krus <mike.krus@kdab.com>
This commit is contained in:
Paul Lemire 2020-02-18 07:42:35 +00:00
parent ecca6d21fb
commit c6fecd32f8
12 changed files with 218 additions and 424 deletions

View File

@ -13,6 +13,7 @@ HEADERS += \
qtquickscene3dplugin.h \
scene3dlogging_p.h \
scene3ditem_p.h \
scene3dcleaner_p.h \
scene3drenderer_p.h \
scene3dsgnode_p.h \
scene3dsgmaterialshader_p.h \
@ -23,6 +24,7 @@ SOURCES += \
qtquickscene3dplugin.cpp \
scene3ditem.cpp \
scene3dlogging.cpp \
scene3dcleaner.cpp \
scene3drenderer.cpp \
scene3dsgnode.cpp \
scene3dsgmaterialshader.cpp \

View File

@ -0,0 +1,75 @@
/****************************************************************************
**
** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "scene3dcleaner_p.h"
#include <Qt3DCore/qaspectengine.h>
#include <QtCore/qthread.h>
#include <scene3dlogging_p.h>
#include <scene3drenderer_p.h>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
Scene3DCleaner::Scene3DCleaner(QObject *parent)
: QObject(parent)
, m_renderer(nullptr)
{
}
Scene3DCleaner::~Scene3DCleaner()
{
qCDebug(Scene3D) << Q_FUNC_INFO << QThread::currentThread();
}
void Scene3DCleaner::cleanup()
{
Q_ASSERT(m_renderer);
delete m_renderer->m_aspectEngine; // also deletes m_renderer->m_renderAspect
m_renderer->m_aspectEngine = nullptr;
m_renderer->m_renderAspect = nullptr;
m_renderer->deleteLater();
deleteLater();
}
} // namespace Qt3DRender
QT_END_NAMESPACE

View File

@ -0,0 +1,82 @@
/****************************************************************************
**
** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QT3DRENDER_SCENE3DCLEANER_P_H
#define QT3DRENDER_SCENE3DCLEANER_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtCore/QObject>
QT_BEGIN_NAMESPACE
namespace Qt3DRender {
class Scene3DRenderer;
class Scene3DCleaner : public QObject
{
Q_OBJECT
public:
explicit Scene3DCleaner(QObject *parent = 0);
~Scene3DCleaner();
void setRenderer(Scene3DRenderer *renderer) { m_renderer = renderer; }
public Q_SLOTS:
void cleanup();
private:
Scene3DRenderer *m_renderer;
};
} // namespace Qt3DRender
QT_END_NAMESPACE
#endif // QT3DRENDER_SCENE3DCLEANER_H

View File

@ -68,6 +68,7 @@
#include <Qt3DRender/private/qrendersurfaceselector_p.h>
#include <Qt3DRender/private/qrenderaspect_p.h>
#include <Qt3DRender/private/rendersettings_p.h>
#include <scene3dcleaner_p.h>
#include <scene3dlogging_p.h>
#include <scene3drenderer_p.h>
#include <scene3dsgnode_p.h>
@ -149,8 +150,8 @@ Scene3DItem::Scene3DItem(QQuickItem *parent)
, m_viewHolderFG(nullptr)
, m_aspectEngine(new Qt3DCore::QAspectEngine())
, m_renderAspect(nullptr)
, m_aspectToDelete(nullptr)
, m_renderer(nullptr)
, m_rendererCleaner(new Scene3DCleaner())
, m_multisample(true)
, m_dirty(true)
, m_dirtyViews(false)
@ -178,8 +179,6 @@ Scene3DItem::~Scene3DItem()
// When the window is closed, it first destroys all of its children. At
// this point, Scene3DItem is destroyed but the Renderer, AspectEngine and
// Scene3DSGNode still exist and will perform their cleanup on their own.
m_aspectEngine->deleteLater();
m_renderer->deleteLater();
}
/*!
@ -205,11 +204,18 @@ QStringList Scene3DItem::aspects() const
*/
Qt3DCore::QEntity *Scene3DItem::entity() const
{
return m_entity.data();
return m_entity;
}
void Scene3DItem::applyAspects()
void Scene3DItem::setAspects(const QStringList &aspects)
{
if (!m_aspects.isEmpty()) {
qCWarning(Scene3D) << "Aspects already set on the Scene3D, ignoring";
return;
}
m_aspects = aspects;
// Aspects are owned by the aspect engine
for (const QString &aspect : qAsConst(m_aspects)) {
if (aspect == QLatin1String("render")) // This one is hardwired anyway
@ -240,26 +246,16 @@ void Scene3DItem::applyAspects()
}
m_aspectEngine->registerAspect(aspect);
}
}
void Scene3DItem::setAspects(const QStringList &aspects)
{
if (!m_aspects.isEmpty()) {
qWarning() << "Aspects already set on the Scene3D, ignoring";
return;
}
m_aspects = aspects;
emit aspectsChanged();
}
void Scene3DItem::setEntity(Qt3DCore::QEntity *entity)
{
if (entity == m_entity.data())
if (entity == m_entity)
return;
m_entity.reset(entity);
m_entity = entity;
emit entityChanged();
}
@ -402,21 +398,14 @@ void Scene3DItem::removeView(Scene3DView *view)
void Scene3DItem::applyRootEntityChange()
{
if (m_aspectEngine->rootEntity() != m_entity.data()) {
m_aspectEngine->setRootEntity(m_entity);
/* If we changed window, the old aspect engine must be deleted only after we have set
the root entity for the new one so that it doesn't delete the root node. */
if (m_aspectToDelete) {
delete m_aspectToDelete;
m_aspectToDelete = nullptr;
}
if (m_aspectEngine->rootEntity() != m_entity) {
m_aspectEngine->setRootEntity(Qt3DCore::QEntityPtr(m_entity));
// Set the render surface
if (!m_entity)
return;
setWindowSurface(entity());
setWindowSurface(m_entity);
if (m_cameraAspectRatioMode == AutomaticAspectRatio) {
// Set aspect ratio of first camera to match the window
@ -492,8 +481,6 @@ void Scene3DItem::onBeforeSync()
// if the Scene3D item is not visible
if (!isVisible() && dontRenderWhenHidden)
return;
if (m_renderer->m_resetRequested)
return;
Q_ASSERT(QThread::currentThread() == thread());
@ -509,7 +496,7 @@ void Scene3DItem::onBeforeSync()
// Make renderer aware of any Scene3DView we are dealing with
if (m_dirtyViews) {
// Scene3DViews checks
if (entity() != m_viewHolderEntity) {
if (m_entity != m_viewHolderEntity) {
qCWarning(Scene3D) << "Scene3DView is not supported if the Scene3D entity property has been set";
}
if (!usesFBO) {
@ -557,48 +544,30 @@ void Scene3DItem::requestUpdate()
}
}
void Scene3DItem::updateWindowSurface()
{
if (!m_entity || !m_dummySurface)
return;
Qt3DRender::QRenderSurfaceSelector *surfaceSelector =
Qt3DRender::QRenderSurfaceSelectorPrivate::find(entity());
if (surfaceSelector) {
if (QWindow *rw = QQuickRenderControl::renderWindowFor(this->window())) {
m_dummySurface->deleteLater();
createDummySurface(rw, surfaceSelector);
}
}
}
void Scene3DItem::setWindowSurface(QObject *rootObject)
{
Qt3DRender::QRenderSurfaceSelector *surfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(rootObject);
// Set the item's window surface if it appears
// the surface wasn't set on the surfaceSelector
if (surfaceSelector && !surfaceSelector->surface()) {
// We may not have a real, exposed QQuickWindow when the Quick rendering
// is redirected via QQuickRenderControl (f.ex. QQuickWidget).
if (QWindow *rw = QQuickRenderControl::renderWindowFor(this->window())) {
createDummySurface(rw, surfaceSelector);
// rw is the top-level window that is backed by a native window. Do
// not use that though since we must not clash with e.g. the widget
// backingstore compositor in the gui thread.
m_dummySurface = new QOffscreenSurface;
m_dummySurface->setParent(qGuiApp); // parent to something suitably long-living
m_dummySurface->setFormat(rw->format());
m_dummySurface->setScreen(rw->screen());
m_dummySurface->create();
surfaceSelector->setSurface(m_dummySurface);
} else {
surfaceSelector->setSurface(this->window());
}
}
}
void Scene3DItem::createDummySurface(QWindow *rw, Qt3DRender::QRenderSurfaceSelector *surfaceSelector)
{
// rw is the top-level window that is backed by a native window. Do
// not use that though since we must not clash with e.g. the widget
// backingstore compositor in the gui thread.
m_dummySurface = new QOffscreenSurface;
m_dummySurface->setParent(qGuiApp); // parent to something suitably long-living
m_dummySurface->setFormat(rw->format());
m_dummySurface->setScreen(rw->screen());
m_dummySurface->create();
surfaceSelector->setSurface(m_dummySurface);
}
/*!
\qmlmethod void Scene3D::setItemAreaAndDevicePixelRatio(size area, real devicePixelRatio)
@ -606,8 +575,7 @@ void Scene3DItem::createDummySurface(QWindow *rw, Qt3DRender::QRenderSurfaceSele
*/
void Scene3DItem::setItemAreaAndDevicePixelRatio(QSize area, qreal devicePixelRatio)
{
Qt3DRender::QRenderSurfaceSelector *surfaceSelector
= Qt3DRender::QRenderSurfaceSelectorPrivate::find(entity());
Qt3DRender::QRenderSurfaceSelector *surfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(m_entity);
if (surfaceSelector) {
surfaceSelector->setExternalRenderTargetSize(area);
surfaceSelector->setSurfacePixelRatio(devicePixelRatio);
@ -697,16 +665,6 @@ void Scene3DItem::setMultisample(bool enable)
QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNodeData *)
{
// m_resetRequested is set to true by Scene3DRenderer::shutdown()
if (m_renderer && m_renderer->m_resetRequested) {
QObject::disconnect(m_windowConnection);
m_renderAspect = nullptr;
m_aspectToDelete = m_aspectEngine;
m_aspectEngine = new Qt3DCore::QAspectEngine();
m_aspectEngine->setRunMode(Qt3DCore::QAspectEngine::Manual);
applyAspects();
m_renderer->m_resetRequested = false;
}
// If the render aspect wasn't created yet, do so now
if (m_renderAspect == nullptr) {
m_renderAspect = new QRenderAspect(QRenderAspect::Synchronous);
@ -717,24 +675,16 @@ QSGNode *Scene3DItem::updatePaintNode(QSGNode *node, QQuickItem::UpdatePaintNode
// Before Synchronizing is in the SG Thread, we want beforeSync to be triggered
// in the context of the main thread
m_windowConnection = QObject::connect(window(), &QQuickWindow::afterAnimating,
this, &Scene3DItem::onBeforeSync, Qt::DirectConnection);
QObject::connect(window(), &QQuickWindow::afterAnimating,
this, &Scene3DItem::onBeforeSync, Qt::DirectConnection);
auto renderAspectPriv = static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect));
QObject::connect(renderAspectPriv->m_aspectManager->changeArbiter(), &Qt3DCore::QChangeArbiter::receivedChange,
this, [this] { m_dirty = true; }, Qt::DirectConnection);
}
if (m_renderer == nullptr) {
m_renderer = new Scene3DRenderer();
m_renderer->init(this, m_aspectEngine, m_renderAspect);
} else if (m_renderer->renderAspect() != m_renderAspect) {
// If the renderer's renderAspect is not equal to the aspect used
// by the item, then it means that we have created a new one due to
// the fact that shutdown() was called on the renderer previously.
// This is a typical situation when the window the item is in has
// moved from one screen to another.
updateWindowSurface();
m_renderer->init(this, m_aspectEngine, m_renderAspect);
m_renderer = new Scene3DRenderer(this, m_aspectEngine, m_renderAspect);
m_renderer->setCleanerHelper(m_rendererCleaner);
}
const bool usesFBO = m_compositingMode == FBO;
const bool hasScene3DViews = !m_views.empty();

View File

@ -71,7 +71,6 @@ class Scene3DRenderer;
class Scene3DCleaner;
class Scene3DView;
class QFrameGraphNode;
class QRenderSurfaceSelector;
class Scene3DItem : public QQuickItem
{
@ -139,20 +138,16 @@ private:
void updateCameraAspectRatio();
void mousePressEvent(QMouseEvent *event) override;
bool needsRender();
void updateWindowSurface();
void createDummySurface(QWindow *window, QRenderSurfaceSelector *surfaceSelector);
void applyAspects();
QStringList m_aspects;
// Store as shared pointer so that aspect engine doesn't delete it.
QSharedPointer<Qt3DCore::QEntity> m_entity;
Qt3DCore::QEntity *m_entity;
Qt3DCore::QEntity *m_viewHolderEntity;
Qt3DRender::QFrameGraphNode *m_viewHolderFG;
Qt3DCore::QAspectEngine *m_aspectEngine;
Qt3DCore::QAspectEngine *m_aspectToDelete;
QRenderAspect *m_renderAspect;
Scene3DRenderer *m_renderer;
Scene3DCleaner *m_rendererCleaner;
bool m_multisample;
bool m_dirty;
@ -165,7 +160,6 @@ private:
CompositingMode m_compositingMode;
QOffscreenSurface *m_dummySurface;
QVector<Scene3DView *> m_views;
QMetaObject::Connection m_windowConnection;
};
} // Qt3DRender

View File

@ -53,6 +53,7 @@
#include <Qt3DCore/private/qchangearbiter_p.h>
#include <Qt3DCore/private/qservicelocator_p.h>
#include <scene3dcleaner_p.h>
#include <scene3ditem_p.h>
#include <scene3dlogging_p.h>
#include <scene3dsgnode_p.h>
@ -143,15 +144,16 @@ private:
signal of the window is not called. Therefore the cleanup method is invoked
to properly destroy the aspect engine.
*/
Scene3DRenderer::Scene3DRenderer()
Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *aspectEngine, QRenderAspect *renderAspect)
: QObject()
, m_item(nullptr)
, m_aspectEngine(nullptr)
, m_renderAspect(nullptr)
, m_item(item)
, m_aspectEngine(aspectEngine)
, m_renderAspect(renderAspect)
, m_multisampledFBO(nullptr)
, m_finalFBO(nullptr)
, m_texture(nullptr)
, m_node(nullptr)
, m_cleaner(nullptr)
, m_window(nullptr)
, m_multisample(false) // this value is not used, will be synced from the Scene3DItem instead
, m_lastMultisample(false)
@ -163,17 +165,6 @@ Scene3DRenderer::Scene3DRenderer()
, m_allowRendering(0)
, m_compositingMode(Scene3DItem::FBO)
{
}
void Scene3DRenderer::init(Scene3DItem *item, Qt3DCore::QAspectEngine *aspectEngine,
QRenderAspect *renderAspect)
{
m_item = item;
m_window = m_item->window();
m_aspectEngine = aspectEngine;
m_renderAspect = renderAspect;
m_needsShutdown = true;
Q_CHECK_PTR(m_item);
Q_CHECK_PTR(m_item->window());
@ -224,14 +215,21 @@ void Scene3DRenderer::scheduleRootEntityChange()
QMetaObject::invokeMethod(m_item, "applyRootEntityChange", Qt::QueuedConnection);
}
void Scene3DRenderer::setCleanerHelper(Scene3DCleaner *cleaner)
{
m_cleaner = cleaner;
if (m_cleaner) {
// Window closed case
QObject::connect(m_item->window(), &QQuickWindow::destroyed, m_cleaner, &Scene3DCleaner::cleanup);
m_cleaner->setRenderer(this);
}
}
// Executed in the QtQuick render thread (which may even be the gui/main with QQuickWidget / RenderControl).
void Scene3DRenderer::shutdown()
{
qCDebug(Scene3D) << Q_FUNC_INFO << QThread::currentThread();
// In case the same item is rendered on another window reset it
m_resetRequested = true;
// Set to null so that subsequent calls to render
// would return early
m_item = nullptr;
@ -245,14 +243,8 @@ void Scene3DRenderer::shutdown()
// Shutdown the Renderer Aspect while the OpenGL context
// is still valid
if (m_renderAspect) {
if (m_renderAspect)
static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderShutdown();
m_aspectEngine->unregisterAspect(m_renderAspect); // deletes render aspect
m_renderAspect = nullptr;
}
m_aspectEngine = nullptr;
m_finalFBO.reset();
m_multisampledFBO.reset();
}
// QtQuick render thread (which may also be the gui/main thread with QQuickWidget / RenderControl)
@ -262,6 +254,7 @@ void Scene3DRenderer::onSceneGraphInvalidated()
if (m_needsShutdown) {
m_needsShutdown = false;
shutdown();
QMetaObject::invokeMethod(m_cleaner, "cleanup");
}
}
@ -272,6 +265,7 @@ void Scene3DRenderer::onWindowChanged(QQuickWindow *w)
if (m_needsShutdown) {
m_needsShutdown = false;
shutdown();
QMetaObject::invokeMethod(m_cleaner, "cleanup");
}
}
}

View File

@ -78,7 +78,9 @@ class Scene3DRenderer : public QObject
{
Q_OBJECT
public:
Scene3DRenderer();
Scene3DRenderer(Scene3DItem *item,
Qt3DCore::QAspectEngine *aspectEngine,
QRenderAspect *renderAspect);
~Scene3DRenderer();
void setSGNode(Scene3DSGNode *node);
@ -87,12 +89,7 @@ public:
void setCompositingMode(Scene3DItem::CompositingMode mode);
void setSkipFrame(bool skip);
void setScene3DViews(const QVector<Scene3DView *> views);
void init(Scene3DItem *item, Qt3DCore::QAspectEngine *aspectEngine, QRenderAspect *renderAspect);
QRenderAspect *renderAspect() const
{
return m_renderAspect;
}
public Q_SLOTS:
void render();
void shutdown();
@ -106,12 +103,13 @@ private:
void scheduleRootEntityChange();
Scene3DItem *m_item; // Will be released by the QQuickWindow/QML Engine
Qt3DCore::QAspectEngine *m_aspectEngine; // Will be released by the Scene3DItem
Qt3DCore::QAspectEngine *m_aspectEngine; // Will be released by the Scene3DRendererCleaner
QRenderAspect *m_renderAspect; // Will be released by the aspectEngine
QScopedPointer<QOpenGLFramebufferObject> m_multisampledFBO;
QScopedPointer<QOpenGLFramebufferObject> m_finalFBO;
QScopedPointer<QSGTexture> m_texture;
Scene3DSGNode *m_node; // Will be released by the QtQuick SceneGraph
Scene3DCleaner *m_cleaner;
QQuickWindow *m_window;
QMutex m_windowMutex;
QSize m_lastSize;
@ -125,9 +123,8 @@ private:
QSemaphore m_allowRendering;
Scene3DItem::CompositingMode m_compositingMode;
QVector<Scene3DView *> m_views;
bool m_resetRequested = false;
friend class Scene3DItem;
friend class Scene3DCleaner;
};
} // namespace Qt3DRender

View File

@ -88,8 +88,3 @@ qtHaveModule(widgets): {
rendercapture-cpp \
texture-updates-cpp
}
qtHaveModule(quickwidgets): {
SUBDIRS += quickwidget-switch
}

View File

@ -1,125 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QDesktopWidget>
#include <QScreen>
#include <QApplication>
#include <QMainWindow>
#include <QMdiArea>
#include <QMdiSubWindow>
#include <QQuickWidget>
#include <QVBoxLayout>
#include <QPushButton>
void configureMainWindow(QMainWindow *w, QMdiArea *mdiArea, QPushButton *button)
{
auto widget = new QWidget;
auto layout = new QVBoxLayout;
layout->addWidget(mdiArea);
layout->addWidget(button);
widget->setLayout(layout);
w->setCentralWidget(widget);
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QMainWindow w1;
w1.winId();
w1.windowHandle()->setScreen(QGuiApplication::screens().at(0));
auto mdiArea1 = new QMdiArea;
auto button1 = new QPushButton("Switch to other window");
configureMainWindow(&w1, mdiArea1, button1);
w1.setGeometry(0, 0, 800, 800);
w1.show();
QMainWindow w2;
w2.winId();
w2.windowHandle()->setScreen(QGuiApplication::screens().at(1));
auto mdiArea2 = new QMdiArea;
auto button2 = new QPushButton("Switch to other window");
configureMainWindow(&w2, mdiArea2, button2);
w2.setGeometry(0, 0, 800, 800);
w2.show();
QMdiSubWindow* subWindow = new QMdiSubWindow();
QQuickWidget *quickWidget = new QQuickWidget();
quickWidget->resize(QSize(400, 400));
quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
quickWidget->setSource(QUrl("qrc:/main.qml"));
subWindow->setWidget(quickWidget);
QObject::connect(button1, &QPushButton::clicked,
[mdiArea1, mdiArea2, subWindow, button1, button2]() {
mdiArea2->removeSubWindow(subWindow);
mdiArea1->addSubWindow(subWindow);
subWindow->show();
button1->setEnabled(false);
button2->setEnabled(true);
});
QObject::connect(button2, &QPushButton::clicked,
[mdiArea1, mdiArea2, subWindow, button1, button2]() {
mdiArea1->removeSubWindow(subWindow);
mdiArea2->addSubWindow(subWindow);
subWindow->show();
button1->setEnabled(true);
button2->setEnabled(false);
});
mdiArea2->addSubWindow(subWindow);
button2->setEnabled(false);
subWindow->show();
return app.exec();
}

View File

@ -1,152 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2019 The Qt Company.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.2 as QQ2
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
import QtQuick.Scene3D 2.0
QQ2.Item {
id: mioitem
width: 300
height: 300
Scene3D {
id: scene3d
anchors.fill: parent
Entity {
id: sceneRoot
Camera {
id: camera
projectionType: CameraLens.PerspectiveProjection
fieldOfView: 45
aspectRatio: 16/9
nearPlane : 0.1
farPlane : 1000.0
position: Qt.vector3d( 0.0, 0.0, -40.0 )
upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
}
OrbitCameraController {
camera: camera
}
components: [
RenderSettings {
activeFrameGraph: ForwardRenderer {
clearColor: Qt.rgba(0, 0.5, 1, 1)
camera: camera
}
},
// Event Source will be set by the Qt3DQuickWindow
InputSettings { }
]
PhongMaterial {
id: material
}
TorusMesh {
id: torusMesh
radius: 5
minorRadius: 1
rings: 100
slices: 20
}
Transform {
id: torusTransform
scale3D: Qt.vector3d(1.5, 1, 0.5)
rotation: fromAxisAndAngle(Qt.vector3d(1, 0, 0), 45)
}
Entity {
id: torusEntity
components: [ torusMesh, material, torusTransform ]
}
SphereMesh {
id: sphereMesh
radius: 3
}
Transform {
id: sphereTransform
property real userAngle: 0.0
matrix: {
var m = Qt.matrix4x4();
m.rotate(userAngle, Qt.vector3d(0, 1, 0));
m.translate(Qt.vector3d(20, 0, 0));
return m;
}
}
QQ2.NumberAnimation {
target: sphereTransform
property: "userAngle"
duration: 10000
from: 0
to: 360
loops: QQ2.Animation.Infinite
running: true
}
Entity {
id: sphereEntity
components: [ sphereMesh, material, sphereTransform ]
}
}
}
}

View File

@ -1,13 +0,0 @@
TEMPLATE = app
QT += 3dextras
CONFIG += resources_big
QT += 3dcore 3drender 3dinput 3dquick 3dlogic qml quick 3dquickextras widgets quickwidgets
SOURCES += \
main.cpp
RESOURCES += \
quickwidget-switch.qrc

View File

@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
</qresource>
</RCC>