aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quick/quickwidgets/quickwidget
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2016-06-20 11:00:39 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2016-06-20 15:50:32 +0000
commitb30d970691e9a6abf56bacb53a2d3f734d6f031c (patch)
tree455c5e3eb9ca5c33449c09c4c0a436cd5608689e /examples/quick/quickwidgets/quickwidget
parentcc4954e9646cd93d9710e4e28942d2a82762771e (diff)
Add a tab widget to QQuickWidget example
...and include a tab with custom OpenGL rendering. Tab widgets are interesting because they are commonly used in applications in combination with widgets like QOpenGLWidget and QQuickWidget, and because they typically trigger rapid show-hide sequences which QQuickWidget does not always handle as well as it could. Thus this serves both as a helpful example and a useful testing tool. Plus it exposes at least two bugs already, namely that the continuous animation in the QQuickFBO does not start when switching to the tab containing the QQuickWidget in question, and that it is impossible to integrate third-party rendering code in a robust manner due to QQuickWidget destroying everything whenever hiding the widget. This is not what happens with a QQuickView and the normal render loops. Task-number: QTBUG-54133 Change-Id: Ie7d92cd0f685e4a26f4bb351cc023eb697a36bf4 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'examples/quick/quickwidgets/quickwidget')
-rw-r--r--examples/quick/quickwidgets/quickwidget/customgl.qml59
-rw-r--r--examples/quick/quickwidgets/quickwidget/fbitem.cpp90
-rw-r--r--examples/quick/quickwidgets/quickwidget/fbitem.h53
-rw-r--r--examples/quick/quickwidgets/quickwidget/main.cpp38
-rw-r--r--examples/quick/quickwidgets/quickwidget/quickwidget.pro3
-rw-r--r--examples/quick/quickwidgets/quickwidget/quickwidget.qrc2
-rw-r--r--examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml66
7 files changed, 307 insertions, 4 deletions
diff --git a/examples/quick/quickwidgets/quickwidget/customgl.qml b/examples/quick/quickwidgets/quickwidget/customgl.qml
new file mode 100644
index 0000000000..81e33e1ac9
--- /dev/null
+++ b/examples/quick/quickwidgets/quickwidget/customgl.qml
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.0
+import QuickWidgetExample 1.0
+
+Rectangle {
+ color: "lightGray"
+
+ FbItem {
+ anchors.fill: parent
+ anchors.margins: 10
+ }
+
+ Text {
+ anchors.left: parent.left
+ anchors.bottom: parent.bottom
+ anchors.margins: 15
+ text: "QQuickFramebufferObject with animated clear color"
+ color: "white"
+ }
+}
diff --git a/examples/quick/quickwidgets/quickwidget/fbitem.cpp b/examples/quick/quickwidgets/quickwidget/fbitem.cpp
new file mode 100644
index 0000000000..fc2a4ea7ad
--- /dev/null
+++ b/examples/quick/quickwidgets/quickwidget/fbitem.cpp
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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 "fbitem.h"
+#include <QtGui/QOpenGLFramebufferObject>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFunctions>
+#include <QtCore/QDebug>
+
+#ifndef QT_NO_OPENGL
+class FbRenderer : public QQuickFramebufferObject::Renderer
+{
+public:
+ FbRenderer() : c(0), dir(1) { }
+
+ // The lifetime of the FBO and this class depends on how QQuickWidget
+ // manages the scenegraph and context when it comes to showing and hiding
+ // the widget. The actual behavior is proven by the debug prints.
+ ~FbRenderer() {
+ qDebug("FbRenderer destroyed");
+ }
+
+ void render() {
+ QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
+ f->glClearColor(c, 0, 0, 1);
+ f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ c += 0.01f * dir;
+ if (c >= 1.0f || c <= 0.0f)
+ dir *= -1;
+ update();
+ }
+
+ QOpenGLFramebufferObject *createFramebufferObject(const QSize &size) {
+ qDebug() << "Creating FBO" << size;
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
+ return new QOpenGLFramebufferObject(size, format);
+ }
+
+private:
+ float c;
+ int dir;
+};
+#endif
+
+QQuickFramebufferObject::Renderer *FbItem::createRenderer() const
+{
+#ifndef QT_NO_OPENGL
+ return new FbRenderer;
+#else
+ return nullptr;
+#endif
+}
diff --git a/examples/quick/quickwidgets/quickwidget/fbitem.h b/examples/quick/quickwidgets/quickwidget/fbitem.h
new file mode 100644
index 0000000000..59280eb3b8
--- /dev/null
+++ b/examples/quick/quickwidgets/quickwidget/fbitem.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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$
+**
+****************************************************************************/
+
+#ifndef FBITEM_H
+#define FBITEM_H
+
+#include <QtQuick/QQuickFramebufferObject>
+
+class FbItem : public QQuickFramebufferObject
+{
+ Q_OBJECT
+public:
+ Renderer *createRenderer() const;
+};
+
+#endif
diff --git a/examples/quick/quickwidgets/quickwidget/main.cpp b/examples/quick/quickwidgets/quickwidget/main.cpp
index 65258d958e..2f73447a5d 100644
--- a/examples/quick/quickwidgets/quickwidget/main.cpp
+++ b/examples/quick/quickwidgets/quickwidget/main.cpp
@@ -41,6 +41,7 @@
#include <QQuickWidget>
#include <QQmlError>
#include <QtWidgets>
+#include "fbitem.h"
class MainWindow : public QMainWindow {
Q_OBJECT
@@ -52,6 +53,7 @@ private slots:
void sceneGraphError(QQuickWindow::SceneGraphError error, const QString &message);
void grabToFile();
void renderToFile();
+ void createQuickWidgetsInTabs(QMdiArea *mdiArea);
private:
QQuickWidget *m_quickWidget;
@@ -74,7 +76,7 @@ MainWindow::MainWindow()
QLCDNumber *lcd = new QLCDNumber;
lcd->display(1337);
lcd->setMinimumSize(250,100);
- centralWidget ->addSubWindow(lcd);
+ centralWidget->addSubWindow(lcd);
QUrl source("qrc:quickwidget/rotatingsquare.qml");
@@ -86,14 +88,42 @@ MainWindow::MainWindow()
m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView );
m_quickWidget->setSource(source);
- centralWidget ->addSubWindow(m_quickWidget);
+ centralWidget->addSubWindow(m_quickWidget);
setCentralWidget(centralWidget);
QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
- fileMenu->addAction(tr("Grab to imFage"), this, &MainWindow::grabToFile);
+ fileMenu->addAction(tr("Grab to image"), this, &MainWindow::grabToFile);
fileMenu->addAction(tr("Render to pixmap"), this, &MainWindow::renderToFile);
fileMenu->addAction(tr("Quit"), qApp, &QCoreApplication::quit);
+
+ QMenu *windowMenu = menuBar()->addMenu(tr("&Window"));
+ windowMenu->addAction(tr("Add tab widget"), this,
+ [this, centralWidget] { createQuickWidgetsInTabs(centralWidget); });
+}
+
+void MainWindow::createQuickWidgetsInTabs(QMdiArea *mdiArea)
+{
+ QTabWidget *tabWidget = new QTabWidget;
+
+ const QSize size(400, 400);
+
+ QQuickWidget *w = new QQuickWidget;
+ w->resize(size);
+ w->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ w->setSource(QUrl("qrc:quickwidget/rotatingsquaretab.qml"));
+
+ tabWidget->addTab(w, tr("Plain Quick content"));
+
+ w = new QQuickWidget;
+ w->resize(size);
+ w->setResizeMode(QQuickWidget::SizeRootObjectToView);
+ w->setSource(QUrl("qrc:quickwidget/customgl.qml"));
+
+ tabWidget->addTab(w, tr("Custom OpenGL drawing"));
+
+ mdiArea->addSubWindow(tabWidget);
+ tabWidget->show();
}
void MainWindow::quickWidgetStatusChanged(QQuickWidget::Status status)
@@ -139,6 +169,8 @@ int main(int argc, char **argv)
{
QApplication app(argc, argv);
+ qmlRegisterType<FbItem>("QuickWidgetExample", 1, 0, "FbItem");
+
MainWindow mainWindow;
mainWindow.show();
diff --git a/examples/quick/quickwidgets/quickwidget/quickwidget.pro b/examples/quick/quickwidgets/quickwidget/quickwidget.pro
index 04fb5541a7..5be006f7fa 100644
--- a/examples/quick/quickwidgets/quickwidget/quickwidget.pro
+++ b/examples/quick/quickwidgets/quickwidget/quickwidget.pro
@@ -3,7 +3,8 @@ QT += core gui quick widgets quickwidgets
TARGET = quickwidget
TEMPLATE = app
-SOURCES += main.cpp
+SOURCES += main.cpp fbitem.cpp
+HEADERS += fbitem.h
RESOURCES += quickwidget.qrc
diff --git a/examples/quick/quickwidgets/quickwidget/quickwidget.qrc b/examples/quick/quickwidgets/quickwidget/quickwidget.qrc
index c073b7b80d..85a49b75ca 100644
--- a/examples/quick/quickwidgets/quickwidget/quickwidget.qrc
+++ b/examples/quick/quickwidgets/quickwidget/quickwidget.qrc
@@ -1,5 +1,7 @@
<RCC>
<qresource prefix="/quickwidget">
<file>rotatingsquare.qml</file>
+ <file>rotatingsquaretab.qml</file>
+ <file>customgl.qml</file>
</qresource>
</RCC>
diff --git a/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml b/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml
new file mode 100644
index 0000000000..51c17b9ffb
--- /dev/null
+++ b/examples/quick/quickwidgets/quickwidget/rotatingsquaretab.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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.0
+
+Rectangle {
+ gradient: Gradient {
+ GradientStop { position: 0; color: "steelblue" }
+ GradientStop { position: 1; color: "black" }
+ }
+
+ Rectangle {
+ property int d: 100
+ id: square
+ width: d
+ height: d
+ anchors.centerIn: parent
+ color: "green"
+ NumberAnimation on rotation { from: 360; to: 0; duration: 4000; loops: Animation.Infinite; }
+ }
+
+ Text {
+ anchors.centerIn: parent
+ text: "Qt Quick running in a tab widget"
+ color: "purple"
+ font.bold: true
+ font.pointSize: 14
+ }
+}