QDeclarativeComponent Problem

Alles rund um die Programmierung mit Qt
Antworten
Psychomax
Beiträge: 52
Registriert: 29. Dezember 2008 13:28

QDeclarativeComponent Problem

Beitrag von Psychomax »

Hallo zusammen!

Folgendes Programm knallt. Und ich hab keine Ahnung wieso. Erstmal den Code. Es ist nur ein Democode. Das ganze Framework wollte ich jetzt nicht posten.

Code: Alles auswählen

.pro

QT       += core gui declarative

TARGET = Test4
TEMPLATE = app


SOURCES += main.cpp \
    switcher.cpp

OTHER_FILES += \
    qml1.qml \
    qml2.qml

HEADERS += \
    switcher.h

Code: Alles auswählen

switcher.h

#ifndef SWITCHER_H
#define SWITCHER_H

#include <QGraphicsScene>
#include <QtDeclarative>
#include <QGraphicsObject>

class QmlContainer : public QObject
{
	Q_OBJECT
public:
	QmlContainer(QString s,QDeclarativeEngine *engine);
	~QmlContainer();
	QGraphicsObject * retObj();

public slots:
	void click();
signals:
	void itemClicked();
private:
	QDeclarativeEngine *m_engine;
	QDeclarativeComponent *m_qmlComponent;
	QGraphicsObject *obj;
	QDeclarativeContext *m_qmlContext;

};

class Switcher : public QObject
{
    Q_OBJECT
public:
    Switcher(QGraphicsScene *scene,
	     QDeclarativeEngine *engine,
	     QObject *parent = 0);
    ~Switcher();
signals:

public slots:
	void changeqml();
private:
    QGraphicsScene *m_scene;
    QDeclarativeEngine *m_engine;
    QmlContainer *m_a;
    QmlContainer *m_b;
    QGraphicsObject *m_obj;
};



#endif // SWITCHER_H

Code: Alles auswählen

switcher.cpp

#include "switcher.h"

Switcher::Switcher(QGraphicsScene *scene,
		   QDeclarativeEngine *engine,
		   QObject *parent) :
    QObject(parent)
{
	m_scene = scene;
	m_engine = engine;

	m_a = new QmlContainer("qml1.qml", m_engine);
	m_obj = m_a->retObj();

	m_scene->addItem(qobject_cast <QGraphicsItem*> (m_obj));

	connect(m_a, SIGNAL(itemClicked()), this, SLOT(changeqml()));
}

Switcher::~Switcher()
{}

void Switcher::changeqml()
{
	qDebug("CHANGE");
	m_scene->removeItem(qobject_cast <QGraphicsItem*> (m_obj));

	m_b = new QmlContainer("qml2.qml", m_engine);
	m_obj = m_b->retObj();
	m_scene->addItem(qobject_cast <QGraphicsItem*> (m_obj));

	delete m_a;
}

QmlContainer::QmlContainer(QString s, QDeclarativeEngine *engine)
	: QObject(0)
{
	m_engine = engine;
	m_qmlContext = new QDeclarativeContext(m_engine->rootContext());
	m_qmlContext->setContextProperty("qmlcontainer",  this);
	m_qmlComponent = new QDeclarativeComponent(m_engine,
						    QUrl(s),
						    this);
	obj = qobject_cast<QGraphicsObject *>(m_qmlComponent->create(m_qmlContext));
}

QmlContainer::~QmlContainer()
{
	delete obj;
	delete m_qmlComponent;
}

QGraphicsObject * QmlContainer::retObj()
{
	return obj;
}

void QmlContainer::click()
{
	qDebug("Click");
	emit itemClicked();
}

Code: Alles auswählen

main.cpp

#include <QApplication>
#include <QGraphicsView>
#include <QtDeclarative>
#include <QObject>
#include "switcher.h"

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);

	QDeclarativeEngine *engine = new QDeclarativeEngine;
	QGraphicsScene *scene = new QGraphicsScene;
	QGraphicsView view(scene);
	view.resize(320,240);
	view.show();

	Switcher c(scene, engine);

	return app.exec();
}

Code: Alles auswählen

qml1.qml
import Qt 4.7

Rectangle {
    width: 320
    height: 240

    Text {
	id: text1
	x: 150
	y: 114
	width: 80
	height: 20
	text: "Text One"
    }

    MouseArea {
	id: mouse_area1
	x: 0
	y: 0
	width: 320
	height: 240

	onClicked: {
		qmlcontainer.click();
	}
    }
}

Code: Alles auswählen

qml2.qml

import Qt 4.7

Rectangle {
    width: 320
    height: 240
    color: "#ff0000"
}

SOOOO also.

QmlContainer wird normal gelöscht. Soweit so gut. "obj"(im Destruktor von QmlContainer) muss man scheinbar selber löschen, weil einem sonst der Speicher voll läuft. Wenn man allerdings "obj" auskommentiert dann stürzt das Programm nicht ab. Irgendwie verirrt er sich in irgendwelchen Mousehandler Methoden vom Declarative Module.

Ihr könnt ja mal das Programm ausprobieren. :)

LG Max
Psychomax
Beiträge: 52
Registriert: 29. Dezember 2008 13:28

Beitrag von Psychomax »

JUHU! :) Lösung gefunden. Grund des Absturz war ja, dass er irgendwie noch in der Eventloop rumgegeistert hat. Mit der Methode (deleteLater()) geht es! :-) Nice, oder?! :)
Antworten