我不喜欢这个问题太多,因为它是不是真的问什么特别。 Qt文档非常全面,所以当人们说他们阅读过文档,教程和示例,但仍然没有找到他们想要的东西时,我经常发现它很奇怪。但是,我认为我理解你所问的要点,并认为答案可能对某些人有用,所以我会试着回答它。
的main.cpp
#include <QtGui/QGuiApplication>
#include <QtQml>
#include <QQuickItem>
#include "qtquick2applicationviewer.h"
class ApplicationItem : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QString title MEMBER mTitle NOTIFY titleChanged)
public:
ApplicationItem(QQuickItem *parent = 0) : QQuickItem(parent) {
}
public slots:
void close() {
emit closed(this);
}
signals:
void titleChanged(QString title);
void closed(ApplicationItem *app);
private:
QString mTitle;
};
class SceneItem : public QQuickItem
{
Q_OBJECT
public:
SceneItem() {
}
public slots:
void startApp(const QString &qmlFile) {
QQmlComponent *component = new QQmlComponent(qmlEngine(this), QUrl(qmlFile));
if (component->isLoading()) {
QObject::connect(component, SIGNAL(statusChanged(QQmlComponent::Status)),
this, SLOT(componentStatusChanged()));
} else {
// The component was synchronously loaded, but it may have errors.
if (component->isError()) {
qWarning() << "Failed to start application:" << component->errorString();
} else {
addApp(component);
}
}
}
void componentStatusChanged(QQmlComponent::Status status) {
QQmlComponent *component = qobject_cast<QQmlComponent*>(sender());
if (status == QQmlComponent::Ready) {
addApp(component);
} else if (status == QQmlComponent::Error) {
qWarning() << "Failed to start application:" << component->errorString();
}
}
void appClosed(ApplicationItem *app) {
int appIndex = mApplications.indexOf(app);
if (appIndex != -1) {
mApplications.removeAt(appIndex);
app->deleteLater();
}
}
private:
void addApp(QQmlComponent *component) {
ApplicationItem *appItem = qobject_cast<ApplicationItem*>(component->create());
appItem->setParentItem(this);
connect(appItem, SIGNAL(closed(ApplicationItem*)), this, SLOT(appClosed(ApplicationItem*)));
mApplications.append(appItem);
delete component;
}
QList<ApplicationItem*> mApplications;
};
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
qmlRegisterType<ApplicationItem>("Test", 1, 0, "ApplicationItem");
qmlRegisterType<SceneItem>("Test", 1, 0, "SceneItem");
viewer.setMainQmlFile(QStringLiteral("qml/quick/main.qml"));
viewer.showExpanded();
return app.exec();
}
#include "main.moc"
I表示两个类作为子类QQuickItem。 SceneItem
由许多ApplicationItem
实例组成,它们通过调用startApp()
添加到场景中。此插槽将QML文件的路径作为其参数。该文件可以通过网络或本地文件加载,因此我们考虑了同步和异步加载的可能性。
QML文件应描述应用程序的外观,场景预计其根类型为ApplicationItem
。作为一个例子,这里的MySweetApp.qml:
import QtQuick 2.0
import QtQuick.Controls 1.0
import Test 1.0
ApplicationItem {
id: someAppStyle
title: "My Sweet App"
width: 100
height: 100
MouseArea {
anchors.fill: parent
drag.target: parent
}
Rectangle {
radius: 4
color: "lightblue"
anchors.fill: parent
Text {
anchors.left: parent.left
anchors.right: closeButton.right
anchors.leftMargin: 4
anchors.top: parent.top
anchors.topMargin: 4
text: someAppStyle.title
}
Button {
id: closeButton
anchors.right: parent.right
anchors.rightMargin: 4
anchors.top: parent.top
anchors.topMargin: 2
onClicked: close()
text: "x"
width: 20
height: width
}
}
}
应用程序可以通过调用ApplicationItem
宣布close()
槽封闭自己。
这里的主。QML:
import QtQuick 2.0
import QtQuick.Controls 1.0
import Test 1.0
SceneItem {
id: scene
width: 360
height: 360
Button {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
text: "Launch app"
onClicked: scene.startApp("qml/quick/MySweetApp.qml")
}
}
这就是SceneItem
声明,用一个简单的界面启动我的甜蜜应用程序的多个实例一起(这是一个非常有用的应用程序)。
我相信这是最合适的方式做你的要求。它避免了在C++中设置列表ApplicationItems
的麻烦,这些列表暴露于QML(实际上并不困难,但这是文档可能更明显的一个区域),并允许操作系统的用户自由地显示应用程序。如果你想更加严格的样式,我会建议看看如何Qt Quick Controls造型。
什么问题? “它看起来不像那个”是什么意思?我们需要具体细节。 – Mitch