我已完全编辑了我的问题,因为我取得了一些进展,第一个问题尚不清楚。
我使用Qt 4.8,使用QtQuick 1.0。
我有一个页面,我需要保持顶部和底部边距。所以我已经定义了一个 Main.qml :
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 {[...]}
}
如果我将qml文件放入加载器sourceComponent,它可以工作。 现在我想用C ++做,并且设计得很好。我在 SalesAppDisplay.h
中将QDeclarativeComponent子类化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
[...]
}
和负责组件实例化的 Ctor :
IDisplayScreen::IDisplayScreen(DisplayContext& context, QDeclarativeEngine& engine, std::string qmlFilepath, QObject* parent)
: QDeclarativeComponent(&engine, QString(qmlFilepath.c_str()), parent)
我想通过更改源代码在加载器中加载qml文件,而不是从 main.cpp 中将我的组件插入到QML中:
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();
我已经尝试了loader->setProperty("sourceComponent", qobject_cast<QVariant>(saleAppObj));
,以及其他一些没有任何结果的技巧。
我的saleApp.qml中有错误说他不知道我在其中使用的Main.qml属性(他显然是在组件实例中加载)。尽管main.qml已经完全加载,但是出现了SaleApp.qml。
答案 0 :(得分:1)
我已经成功了。
有屏幕处理功能:
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()是我添加的一个函数,用于删除项目指针而不删除整个组件,只是因为我遇到了一个问题,即在添加新内容时组件未从视图中删除。
SalesApp.qml没有关于MainWindow.qml的引用,所以我添加了两个包装器:
m_view.rootContext()->setContextProperty("managerWrapper", this);
m_view.rootContext()->setContextProperty("appWrapper", m_currentScreen);
效果很好,设计很好,代码很甜。