QML chartview crash when changing data - qt

I'm new to qml and I didn't really get its logic yet.
Here is my issue: I have a chartview with barseries, and I expect that when the user clicks on a bar, the bar chart changes.
So I clear the barSeries and append new data to it. But it causes a segmentation fault.
If I do the same processing from a button click, it works well.
Do you have any idea what is the problem, and how to fix it?
Below is a code sample.
main.qml
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
import QtCharts 2.2
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Chartview test")
Item {
id: histoView
property int globalForJs: 0
anchors.fill: parent
visible: true
Component.onCompleted: {
redraw();
}
signal redrawSignal()
ColumnLayout {
anchors.fill: parent
Button {
id:myBtn
anchors { top: parent.top; left: parent.left; leftMargin: 20 }
height: 30
width: 80
text: "new chart"
onClicked: {
console.debug("myBtn onClicked")
histoView.redrawSignal()
}
}
ChartView {
id: chartView
anchors { bottom: parent.bottom; left: parent.left; right: parent.right }
height: parent.height - 40
title: "chartview"
BarSeries {
id: mySeries
axisX: BarCategoryAxis { categories: [" "] }
axisY: ValueAxis {
id: ordinate
min:0
max:100
}
onClicked: {
console.debug("mySeries onClicked")
histoView.redrawSignal();
//myBtn.clicked()
}
}
}
}
function redraw() {
// clear data
mySeries.clear();
// add 5 new data
for (var i=0;i<5;i++) {
var tab=[];
globalForJs++;
tab.push(globalForJs);
mySeries.append("tutu"+i,tab);
}
// update Y axis maximum value
if (ordinate.max < globalForJs) {
ordinate.max = globalForJs + 10;
}
}
onRedrawSignal:redraw()
}
}
main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}

Short answer:
Looks like a bug in QGraphicsScene or Qt Charts' usage of it. Please report a bug at bugreports.qt.io.
Long answer (debugging crashes in Qt):
When you run into a crash where there's only QML, and nothing suspicious-looking going on in your C++ code, it's probably a bug in Qt. In order to increase the changes of the bug being fixed quickly, it's a good idea to get a stack trace, because the developer may spot a simple fix for it by looking at where it crashes. To get a stack trace, you'll have to build a debug build of Qt.
When debugging your application with a debug build of Qt, I can see that QGraphicsItem::mouseReleaseEvent() is calling a member function of an object that has been deleted. An easy way to verify this is to add some debug code to the destructor of QGraphicsItem that prints out the memory address of each object that is destroyed. In addition, add a line to the beginning of QGraphicsItem::mouseReleaseEvent() that uses qDebug()'s printf syntax (to avoid QGraphicsItem's << operator being called, which would cause a crash before it could print anything):
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index f2b8b66..9f2302d 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
## -1501,6 +1501,7 ## QGraphicsItem::QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent)
*/
QGraphicsItem::~QGraphicsItem()
{
+ qDebug() << Q_FUNC_INFO << this;
if (d_ptr->isObject) {
QGraphicsObject *o = static_cast<QGraphicsObject *>(this);
QObjectPrivate *p = QObjectPrivate::get(o);
## -7328,6 +7329,7 ## void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
*/
void QGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
+ qDebug("About to access %p\n", this);
if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
if (event->scenePos() == event->buttonDownScenePos(Qt::LeftButton)) {
Build qtbase and then debug your application again. The stack trace will now look something like this (copied from Creator):
1 QGraphicsItem::flags qgraphicsitem.cpp 1854 0x6dcf8cf9
2 QGraphicsItem::mouseReleaseEvent qgraphicsitem.cpp 7333 0x6dd05003
3 QtCharts::Bar::mouseReleaseEvent bar.cpp 90 0x7ffd83fd4a9b
4 QGraphicsItem::sceneEvent qgraphicsitem.cpp 6845 0x6dd03ac6
5 QGraphicsScenePrivate::sendEvent qgraphicsscene.cpp 1251 0x6dd58732
6 QGraphicsScenePrivate::sendMouseEvent qgraphicsscene.cpp 1325 0x6dd594fd
7 QGraphicsScene::mouseReleaseEvent qgraphicsscene.cpp 4099 0x6dd52c26
8 QGraphicsScene::event qgraphicsscene.cpp 3412 0x6dd51423
9 QApplicationPrivate::notify_helper qapplication.cpp 3713 0x6d7772de
10 QApplication::notify qapplication.cpp 3085 0x6d771d83
11 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1013 0x6cf72c16
12 QCoreApplication::sendEvent qcoreapplication.h 231 0x6cf7d5f2
13 QtCharts::DeclarativeChart::mouseReleaseEvent declarativechart.cpp 850 0x7ffd876dd16a
14 QQuickItem::event qquickitem.cpp 7756 0x7ffd7e206583
15 QApplicationPrivate::notify_helper qapplication.cpp 3713 0x6d7772de
16 QApplication::notify qapplication.cpp 3085 0x6d771d83
17 QCoreApplication::notifyInternal2 qcoreapplication.cpp 1013 0x6cf72c16
18 QCoreApplication::sendEvent qcoreapplication.h 231 0x6cf7d5f2
19 QQuickWindow::sendEvent qquickwindow.cpp 2807 0x7ffd7e2305f9
20 QQuickWindowPrivate::deliverMouseEvent qquickwindow.cpp 1671 0x7ffd7e235df1
... <More>
Console output (shortened):
Debugging starts
QML debugging is enabled. Only use this in a safe environment.
QML Debugger: Waiting for connection on port 52234...
[...]
__cdecl QGraphicsItem::~QGraphicsItem(void) QGraphicsItem(0x2da77915480, parent=0x2da77b0fc00, pos=0,0, flags=(ItemIsSelectable))
[...]
About to access 0x2da77915480
You can see that the QGraphicsItem whose memory address is 0x2da77915480 is destroyed, and then its mouseReleaseEvent() function is called.

Related

Wrong screen size value

I created test QML application to show screen size.
It tested on Xiaomi Redmi 6. Device screen resolution is 720 x 1440 pixels.
I have got 360 x 696. Any ideas?
Windows 7 64 bit, Qt 5.14.1, jdk1.8.0_241.
main.qml:
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 720
height: 1440
title: qsTr("Hello World")
Column {
anchors.centerIn: parent
Text {
text: "Screen.width: " + Screen.width
color: "lightsteelblue"
}
Text {
text: "Screen.height: " + Screen.height
color: "lightsteelblue"
}
}
MouseArea {
anchors.fill: parent
onClicked: {
// ScreenSize == QGuiApplication::primaryScreen()->size()
console.log( ScreenSize.height, ScreenSize.width);
}
}
}
console output:
D libTest2_armeabi-v7a.so: qml: 696 360
I made like this: DPI Awareness.
This answer helped me.
int main(int argc, char *argv[])
{
argc = 3;
argv[0] = (char*)"Appname";
argv[1] = (char*)"--platform";
argv[2] = (char*)"android:dpiawareness=0";
QGuiApplication app(argc, argv);
...
}
I changed "windows" to "android".
Now it works correctly.
Although feature don't design for android.
After I delete append code string and it works correctly anyway.
Application works good in the initial state.
Something switched into Qt.

QtQuick's ListView fails to take ownership of QAbstractItemModel object

Based on Qt documentation, whenever a QObject pointer type is passed from C++ code to QML, via a Q_INVOKABLE method, there is a set of rules that determine who is responsible for the lifetime of that pointer. Should the QObject be parentless, implicitly the QML engine is responsible for taking ownership of the pointer.
In my scenario, I want my frontend UI to represent a list model which is generated/provided by the backend C++ code. My assumption is that the pointer will stay alive as long as there is a reference to it by the QML code. The code below shows the trimmed down test case:
Main.cpp
#include <QAbstractItemModel>
#include <QDebug>
#include <QGuiApplication>
#include <QObject>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStringListModel>
class MyStringListModel : public QStringListModel
{
Q_OBJECT
public:
explicit MyStringListModel(const QStringList &strings, QObject* parent=nullptr) : QStringListModel(strings, parent)
{
qDebug() << "Creation";
}
virtual ~MyStringListModel() override
{
qDebug() << "Destruction";
}
};
class Backend : public QObject
{
Q_OBJECT
public:
Backend(QObject* parent=nullptr) : QObject(parent)
{
}
Q_INVOKABLE QAbstractItemModel* createModel() const
{
static const QStringList months = {
tr("January"),
tr("February"),
tr("March"),
tr("April"),
tr("May"),
tr("June"),
tr("July"),
tr("August"),
tr("September"),
tr("October"),
tr("November"),
tr("December"),
};
return new MyStringListModel(months);
}
};
int main(int argc, char* argv[])
{
QGuiApplication application(argc, argv);
qmlRegisterType<QAbstractItemModel>();
Backend backend;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("backend", &backend);
engine.load("qrc:///ui/main.qml");
return application.exec();
}
#include "main.moc"
Main.qml
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.1
ApplicationWindow {
id: window
width: 200
height: 250
visible: true
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
model: backend.createModel()
delegate: Text {
anchors.horizontalCenter: parent.horizontalCenter
text: model.display
}
}
Button {
Layout.alignment: Qt.AlignCenter
text: qsTr("Garbage Collect")
onClicked: gc()
}
}
}
This is a screenshot of the program:
The moment the user clicks on the button, the garbage collector runs and destroys the model ptr (destruction is evident by the "Creation" and "Destruction" output in the stdout).
I'm curious to know why the pointer was destroyed? I've noticed that it didn't set the ListView as its parent, which is fair enough, I thought that the QML engine would have used some form of reference pointer to try keep track of who still holds a reference to it. Is there a document which gives greater insight into the way in which garbage collection / ownership is implemented.
Likewise, is there a better way of structuring this code while still meeting the demands of passing a parentless QObject back to QML.
It seems that the reason for the destruction is because the object is not being referenced in QML, for example if it is assigned to a property the garbage collector will not affect it:
ApplicationWindow {
id: window
width: 200
height: 250
visible: true
property var mymodel: backend.createModel()
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
ListView {
Layout.fillWidth: true
Layout.fillHeight: true
model: mymodel
delegate: Text {
anchors.horizontalCenter: parent.horizontalCenter
text: display
}
}
Button {
Layout.alignment: Qt.AlignCenter
text: qsTr("Garbage Collect")
onClicked: gc()
}
}
}

QSyntaxHighlighter rehighlight() ignores changes triggered from another thread

I have a spellchecking thread which fires spellcheck() signals from time to time which are connected to my highlighter's rehighlight() method. The latter sets the whole block to have red foreground.
This used to work in Qt 5.6.2 and ceased to work in newer versions. I hopelessly waited for it to get fixed in Qt 5.9.5, but it still does not work (neither in Windows 10, nor in OS X).
Small example which reproduces the problem could be obtained from here https://bitbucket.org/ribtoks/qt-highlighting-issue (in order to repro, type something in the input. rehighlight() will be triggered each 7 seconds from background thread)
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQuickTextDocument>
#include <QSyntaxHighlighter>
#include <QThread>
#include <QString>
class SpellCheckWorker : public QObject
{
Q_OBJECT
public:
explicit SpellCheckWorker(QObject *parent = 0) : QObject(parent), m_Counter(0), m_IsOK(false)
{ }
public:
bool isOK() { return m_IsOK; }
signals:
void spellcheck();
public slots:
void process() {
qInfo() << "Worker Thread is" << QThread::currentThreadId();
while (1) {
m_Counter++;
m_IsOK = m_Counter % 7 == 0;
QThread::sleep(1);
emit spellcheck();
}
}
private:
int m_Counter;
volatile bool m_IsOK;
};
class SpellCheckErrorsHighlighter : public QSyntaxHighlighter
{
Q_OBJECT
public:
SpellCheckErrorsHighlighter(SpellCheckWorker *worker, QTextDocument *document):
QSyntaxHighlighter(document),
m_Worker(worker)
{ }
virtual ~SpellCheckErrorsHighlighter() {}
protected:
virtual void highlightBlock(const QString &text) override {
if (!m_Worker->isOK()) {
qDebug() << "Worker is not OK" << text;
return;
}
qInfo() << "Reapplied formatting for" << text;
qInfo() << "Highlight thread is" << QThread::currentThreadId();
this->setFormat(0, text.length(), QColor(0xff, 0, 0));
}
private:
SpellCheckWorker *m_Worker;
};
class MainModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
explicit MainModel(QObject *parent = 0) : QObject(parent), m_Worker(nullptr)
{ }
public:
QString name() const { return m_name; }
void startChecking() {
qInfo() << "Main thread is" << QThread::currentThreadId();
m_Worker = new SpellCheckWorker();
QThread *thread = new QThread();
m_Worker->moveToThread(thread);
QObject::connect(thread, &QThread::started, m_Worker, &SpellCheckWorker::process);
thread->start();
}
Q_INVOKABLE void initNameHighlighting(QQuickTextDocument *document) {
SpellCheckErrorsHighlighter *highlighter = new SpellCheckErrorsHighlighter(m_Worker, document->textDocument());
QObject::connect(m_Worker, &SpellCheckWorker::spellcheck,
highlighter, &SpellCheckErrorsHighlighter::rehighlight);
}
signals:
void nameChanged();
public slots:
void setName(QString name)
{
if (m_name == name)
return;
m_name = name;
emit nameChanged();
}
private:
SpellCheckWorker *m_Worker;
QString m_name;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
MainModel mainModel;
mainModel.startChecking();
QQmlApplicationEngine engine;
QQmlContext *rootContext = engine.rootContext();
rootContext->setContextProperty("mainModel", &mainModel);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
#include "main.moc"
and main.qml
import QtQuick 2.6
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.3
import QtQuick.Window 2.0
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
StackView {
id: mainStackView
anchors.fill: parent
focus: true
initialItem: Rectangle {
anchors.fill: parent
Rectangle {
id: titleRect
height: 30
width: 300
anchors.centerIn: parent
color: "#ffffff"
border.color: "#000000"
border.width: titleTextInput.activeFocus ? 1 : 0
clip: true
focus: false
Flickable {
id: titleFlick
contentWidth: titleTextInput.paintedWidth
contentHeight: titleTextInput.paintedHeight
height: parent.height
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 5
anchors.rightMargin: 5
clip: true
flickableDirection: Flickable.HorizontalFlick
interactive: false
focus: false
function ensureVisible(r) {
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x+r.width)
contentX = r.x+r.width-width;
}
TextEdit {
id: titleTextInput
width: paintedWidth > titleFlick.width ? paintedWidth : titleFlick.width
height: titleFlick.height
text: mainModel.name
focus: true
onTextChanged: mainModel.name = text
Component.onCompleted: mainModel.initNameHighlighting(titleTextInput.textDocument)
onCursorRectangleChanged: titleFlick.ensureVisible(cursorRectangle)
}
}
}
}
}
}
Is there any way to get it working with workarounds? I need to keep spellchecking logic in the background thread so it's not possible to move it to main thread.
You seem to be referring to two different root causes with the following two statements:
There's NO problem in delivering slot call to Highlighter.
and
m_Worker->isOK() check is there for a reason to execute highlighting only once per 7 seconds. The bug in Qt can only be demonstrated with this.
If I just focus on the second statement, it looks like the problem is that you are not able to hit the statement if (!m_Worker->isOK()) right?
That may well be a problem due to your code or a Qt issue on a specific platform.
Can you change the code to avoid the condition i.e. emit the spellcheck signal only when 7 seconds have passed to avoid making this check from another thread?
Ok, so after messing with your code, The issue is that you are not calling this line inside of the hilightBlock directive in main.cpp near line 55 in order to keep the format from before.
Add this in to fix it (I think) The question was still fairly unclear...
if (!m_Worker->isOK()) {
qDebug() << "Worker is not OK" << text;
this->setFormat(0, text.length(), this->format(0));
return;
}
The other part of the issue is that you don't have any rules defined for the syntax highlighter... so it will always be red once it turns red.

How can I reset a timer every time I receive a touch event from a qml page

import QtQuick 2.6;
import QtQuick.Controls 2.1 ;
import QtQuick.Layouts 1.3 ;
Page{
id: page
width: 800
height: 1024
background: Rectangle {
color: "black" ;
anchors.fill:parent ;
}
Rectangle {
id:rect1
x: 0
y:10
width: 100
height: 100
color : "red"
MouseArea {
anchors.fill: parent
onClicked: tmr.restart()
}
}
Rectangle {
id:rect2
x: 0
y:110
width: 100
height: 100
color : "blue"
MouseArea {
anchors.fill: parent
onClicked: tmr.restart()
}
}
Timer {
id : tmr
interval : 30000
repeat : true
running: true
onTriggered: {
console.log ("hello world ")
}
}
}
I develop a software for embedded imx6 freescale device using qt framework.
Basically I just want to restart my timer every time I click and every time I get a touch event on my screen whether the click/touch happen inside the mouse area of my rectangles or outside of them.
The idea is similar to a screensaver.
There are multiple ways, and the right way depends on your requirements.
If you don't need to guarantee that the timer triggers during a input you can just layer a MouseArea on top of everything. In this MouseArea you handle the pressed-signals, but dont accept them.
This allows you to handle the mouse input in the lower layers later. However you only realize whenever a new press happens, and the Timer might trigger e.g. during a half-an-hour finger-move input.
The second way is to have all MouseAreas report uppon their handled signals, that the signal happend, to reset the Timer. For all unhandled signals, you layer a MouseArea beneath everything else, handle all signals there to catch what has been falling through.
Resorting to C++ you might create a Item at the root of your Item-tree, and override the childMouseEventFitler
See my answer here for more on this.
In this case you should add a MouseArea right inside this Item, so it has something to filter at any place.
Note! This method will be triggered for each MouseArea that might be under your click. But in your scenario, this would be fine, I guess.
Thanks to GrecKo I looked into the general eventFilter again, and indeed it is really easy.
you create a simple QObject following the singleton pattern, in which you reimplement the eventFilter-method, so that it will emit a signal
mouseeventspy.h
#pragma once
#include <QObject>
#include <QtQml>
#include <QQmlEngine>
#include <QJSEngine>
class MouseEventSpy : public QObject
{
Q_OBJECT
public:
explicit MouseEventSpy(QObject *parent = 0);
static MouseEventSpy* instance();
static QObject* singletonProvider(QQmlEngine* engine, QJSEngine* script);
protected:
bool eventFilter(QObject* watched, QEvent* event);
signals:
void mouseEventDetected(/*Pass meaningfull information to QML?*/);
};
mouseeventspy.cpp
#include "mouseeventspy.h"
#include <QQmlEngine>
#include <QJSEngine>
#include <QEvent>
MouseEventSpy::MouseEventSpy(QObject *parent) : QObject(parent)
{
qDebug() << "created Instance";
}
// This implements the SINGLETON PATTERN (*usually evil*)
// so you can get the instance in C++
MouseEventSpy* MouseEventSpy::instance()
{
static MouseEventSpy* inst;
if (inst == nullptr)
{
// If no instance has been created yet, creat a new and install it as event filter.
// Uppon first use of the instance, it will automatically
// install itself in the QGuiApplication
inst = new MouseEventSpy();
QGuiApplication* app = qGuiApp;
app->installEventFilter(inst);
}
return inst;
}
// This is the method to fullfill the signature required by
// qmlRegisterSingletonType.
QObject* MouseEventSpy::singletonProvider(QQmlEngine *, QJSEngine *)
{
return MouseEventSpy::instance();
}
// This is the method is necessary for 'installEventFilter'
bool MouseEventSpy::eventFilter(QObject* watched, QEvent* event)
{
QEvent::Type t = event->type();
if ((t == QEvent::MouseButtonDblClick
|| t == QEvent::MouseButtonPress
|| t == QEvent::MouseButtonRelease
|| t == QEvent::MouseMove)
&& event->spontaneous() // Take only mouse events from outside of Qt
)
emit mouseEventDetected();
return QObject::eventFilter(watched, event);
}
Than you register it as singleton type to QML like this:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "mouseeventspy.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterSingletonType<MouseEventSpy>("MouseEventSpy", 1, 0, "MouseEventSpy", MouseEventSpy::singletonProvider);
// We do this now uppon creation of the first instance.
// app.installEventFilter(MouseEventSpy::instance());
engine.load(QUrl(QStringLiteral("main.qml")));
return app.exec();
}
Now in QML you can import the instance of the singleton in the necessary files and use the signal, e.g. to reset a Timer
main.qml
import QtQuick 2.6
import QtQuick.Window 2.2
import MouseEventSpy 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Connections {
target: MouseEventSpy
onMouseEventDetected: myTimer.restart()
}
Timer {
id: myTimer
interval: 1000
onTriggered: console.log('It has been 1 seconds since the last mouse event')
}
Text {
anchors.center: parent
text: myTimer.running ? 'Timer is Running\nMove the mouse to reset'
: 'Move the Mouse to make the timer run again.'
}
}

How to close a Qml window when creating a QGLWidget

I am trying to build a game in which the ui part is made in qml (menu etc) while the rendering and logic part is in C++. For this I'm using a QGLWidget subclass. The game starts with Qml (using a QDeclarativeContext in the main function) and on clicking 'NewGame', I am loading my QGLWidget subclass. Something like this:
GameButton{
id:button2_1_1
x: 69
y: 101
width: 80
height: 80
onClicked:{ myObject.initialize(); myObject.show(); }
}
// myObject sets the context property to the object of my QGLWidget subclass
The problem is that I can't figure out a way to close my Qml window when I load the QGLWidget. As with what I've done two windows are displayed simultaneously.
Here's the code for it.
// import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
import QtQuick 1.1
Rectangle {
id:newGameMenu
width: 640
height: 360
signal button2Clicked();
onButton2Clicked: console.log("new game should start")
Image{
id:background
source:"menubackground.jpg"
anchors.fill:parent
Button2 {
id: button21
x: 70
y: 101
width: 42
height: 42
}
}
Button2{
id:button2_1_1
x: 69
y: 101
width: 44
height: 44
onClicked:{ myObject.abc(); myObject.show(); console.log("glwindow called"); }
}
}
main.cpp
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include <QDeclarativeView>
#include <QDeclarativeItem>
#ifndef GLWINDOW_H
#include "glwindow.h"
#endif
#include <QObject>
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QDeclarativeView view;
GLWindow w;
view.rootContext()->setContextProperty("myObject", &w);
view.setSource(QUrl::fromLocalFile(""));
view.show();
qDebug() << "into the qml";
return app->exec();
}
As with what I've done two windows are displayed simultaneously
I feels like you are showing two window, one QDeclarativeView and other QGLWidget.
In that case, you should try to hide, your QDeclarativeView when you are showing QGLWidget,
see http://qt-project.org/forums/viewthread/4109 which probably answers your question
Try setting .visible=false for the menu widget in onClicked.
What about http://qt-project.org/forums/viewthread/15160/
Also I would use a QStackedWidget with 2 QWidgets: One would be QDeclarativeView that holds your QML and the other QGLWidget that holds your OpenGL; Moving between QML and OpenGL would mean calling QStackedWidget::setCurrent();

Resources