1
votes

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.

1
Have you any particular constraint to prefer QtQuick1 over QtQuick2? Arguments about some differences and similarities of the two can be found here. It would be nice if you could rewrite the first two paragraphs since they are quite unclear. Try also to provide more structured code. - BaCaRoZzo
Yes, I am forced to use QtQuick 1.0 for the moment. I have more code, because I have a working (ugly) solution. I'm looking for a good implementation of what I am already doing. I'll try to edit the question. Thanks - MokaT

1 Answers

1
votes

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.