Reputation: 1416
I've fully edit my question since I've made some progress, and the first one was unclear.
I use Qt 4.8, with QtQuick 1.0.
I have a page where I need to keep the top and the bottom margin. So I've defined a Main.qml like that :
Item {
id: salesWindow
width: 800
height: 600
[...] //Properties def
TopBar {[...]}
CloseButton{[...]}
Rectangle {[...]}
//I want to load qml file in this loader. The QML file loaded use some of the Main.qml properties
Loader {
id: appPlaceHolder
objectName: "loader"
anchors.centerIn: parent
}
Rectangle {[...]}
BotBar {[...]}
}
If I put a qml file into the loader sourceComponent, it works. Now I want to do it with C++, and well designed. I've subclass QDeclarativeComponent in SalesAppDisplay.h
class SalesAppDisplay : public IDisplayScreen
{
Q_OBJECT
static const std::string QML_FILENAME;
static const std::string QML_DIR_PATH;
public:
SalesAppDisplay(DisplayContext& context, QDeclarativeEngine& engine, QObject* parent = 0);
~SalesAppDisplay();
void doScreenInit();
const std::string getQmlFilename() const;
};
class IDisplayScreen : public QDeclarativeComponent
{
Q_OBJECT
[...]
}
and the Ctor in charge of component instanciation :
IDisplayScreen::IDisplayScreen(DisplayContext& context, QDeclarativeEngine& engine, std::string qmlFilepath, QObject* parent)
: QDeclarativeComponent(&engine, QString(qmlFilepath.c_str()), parent)
Instead of loading a qml file in the loader by changing the source, I want to insert my component into the QML from main.cpp :
m_view.setSource(QUrl::fromLocalFile("../displaymanager/rsrc/qml/Main.qml"));
QObject* mainObj = m_view.rootObject();
[ .. Set file property ]
//this is the component subclass instantiation (made by factory)
m_currentScreen = displaymanager::createDisplayScreen(IDisplayScreen::SALESAPP, *(m_context), *(m_view.engine()), mainObj);
QDeclarativeItem* saleAppObj = qobject_cast<QDeclarativeItem*>(m_currentScreen->create(m_view->rootContext()));
saleAppObj->setParentItem(qobject_cast<QDeclarativeItem*>(mainObj));
[ .. Set file property ]
//I can find my loader without any problems
QDeclarativeItem *loader = mainObj->findChild<QDeclarativeItem*>("loader");
/* I don't know what to do here for making it works */
m_view.show();
m_qApp.exec();
I've tried loader->setProperty("sourceComponent", qobject_cast<QVariant>(saleAppObj));
, and some other tricks like that without any results.
I have errors from my saleApp.qml saying that he don't know Main.qml properties that i used in it (he is clearly load at the Components instanciation). And despite that main.qml is perfectly loaded, nothing from SaleApp.qml appears.
Upvotes: 1
Views: 2456
Reputation: 1416
I have made it work.
There is the screen handling function :
void QtDisplayManager::switchScreen(int screenID)
{
if(m_currentScreen)
{
m_currentScreen->destroyItem();
}
//App screen creation
m_currentScreen = displaymanager::createDisplayScreen(screenID, m_context, *m_engine, m_mainObj);
//Get App placehoder
QDeclarativeItem* loaderItem = m_mainObj->findChild<QDeclarativeItem*>("loader");
//Put app in placeholder
if(loaderItem)
{
m_currentScreen->getItem()->setParentItem(loaderItem);
m_engine->clearComponentCache();
m_context.setcurrentDisplayID(screenID);
}
}
destroyItem() is a function I've add to delete item pointer without deleting the whole component, just because I had a problem where the component was not removed from the view when a new was added.
SalesApp.qml have no reference on the MainWindow.qml, so I have add two wrapper :
m_view.rootContext()->setContextProperty("managerWrapper", this);
m_view.rootContext()->setContextProperty("appWrapper", m_currentScreen);
Works perfectly, design is good, code is sweet.
Upvotes: 1