Common
QWidgets were designed for a different type of user interface than QML, so it is not always a good idea to port a QWidget-based application to QML.
QWidgets are a better choice if your UI is comprised of a small number of complex and static elements,
QML is a better choice if your UI is comprised of a large number of simple and dynamic elements.
Basic concept
> QDeclarativeView
QDeclarativeItem objects can be placed on a standard QGraphicsScene and displayed with QGraphicsView.
QGraphicsView subclass, for displaying QML files, connecting between QML and C++ Qt objects.
>QGraphicsItem, QGraphicsObject
QML building
>Build in VC
QML added into qrc, need rebuild because it is part of the dll
If only use the relative path, it can be dynamically loaded.
Properties
[default] property <type> <name>[: defaultValue]
>example
property bool activatedOnce: false
property string launchAppTxt: qsTr("Launch Application")
property int current: 0
property alias dataModel: grid.model
property variant target
Localization
// There is a bug in QML that we can't use qsTr in listElement. So we use QT_TR_NOOP
// http://bugreports.qt.nokia.com/browse/QTBUG-11403
QT_TR_NOOP("Filename");
qsTr(), qsTranslate(), QT_TR_NOOP(), QT_TRANSLATE_NOOP()
http://www.developer.nokia.com/Community/Wiki/QML%E5%9B%BD%E9%99%85%E5%8C%96%E2%80%94%E2%80%94%E4%B8%AD%E6%96%87%E7%A4%BA%E4%BE%8B
--Common End---
Binding
C++ binding
>setSource by QUrl
QDeclarativeView *qmlView = new QDeclarativeView;
qmlView->setSource(QUrl::fromLocalFile("myqml.qml"));
QWidget *widget = myExistingWidget();
QVBoxLayout *layout = new QVBoxLayout(widget);
layout->addWidget(qmlView);
>setSource by QRC
setSource(QUrl("qrc:NotificationHubView.qml"));
>qmlRegisterUncreatableType
registers the C++ type in the QML system with the name qmlName
qmlRegisterUncreatableType<LaunchPadViewImp>("AdLaunchPadUI", 1, 0, "LaunchPadViewImp", "Cannot create LaunchPadViewImp in QML");
Tips
> QMetaType
for unregistered datatype, can't instantiate abstract class
Q_DECLARE_METATYPE / qRegisterMetaType
Context
Contexts allow data to be exposed to the QML components instantiated by the QML engine.
>setContextObject( QObject * object )
Create a Context Class, we can use the Context Class's Property in QML, for single and large Context Class.
>setContextProperty( const QString & name, QObject * value ) or ( const QString & name, const QVariant & value )
Create a Context Class, use it by the name.
Notify
>non-NOTIFYable properties in QML
http://stackoverflow.com/questions/6728615/warning-about-non-notifyable-properties-in-qml
f the property values can change, then QML needs a notify signal so it can know when they have changed and update property bindings.
If they can't change, add CONSTANT to your property declaration, for example Q_PROPERTY(QString simplified READ simplified CONSTANT).
>signal
Q_PROPERTY(bool IsLoggedIn READ GetIsLoggedIn WRITE SetIsLoggedIn NOTIFY loggedInChanged)
WRITE will do the signal connecting and tell UI to update.
Normally we don't need setter because we can also NOTIFY the UI (emit the signal) to update when the property is changed.
>name rule
pattern for properties: <Prop>, Get<Prop>, Set<Prop>, <Prop>Changed (exception is Is* property where getter is same as property name).
---Binding End---
UISettings
Position
>anchors{}: generate usage
For performance reasons, you can only anchor an item to its siblings and direct parent.
Color
>"transparent"
used by some container:color: "transparent"
>opacity
Opacity is specified as a number between 0 (fully transparent) and 1 (fully opaque). The default is 1.
Focus
>ActiveFocus focus: true
>FocusScope Element
Send signal in QML
>C++
QObject* item = pDeclarativeView->rootObject();
if (item)
{
bool ret = connect(item, SIGNAL(linkClicked(QString)), this, SLOT(LinkActivated(QString)));
Q_ASSERT(ret);
}
>QML
signal linkClicked(string link)
onLinkActivated: mainView.linkClicked(link)s
Index
>index
Component Element
Components are reusable, encapsulated QML elements with well-defined interfaces
Image Element
>source: qrc is not enough working for the image path, need add related direcrories like: Image/Sample.png
Text Element
>TextInput/TextEdit
-cursorDelegate, change the shape of the cursor between the text
Flickable Element
>boundsBehavior
Binding Element
>example
Binding {
target: contactName; property: 'text'
value: name; when: list.ListView.isCurrentItem
}
---UISettings End---
QMLDataModels
ListView Element(Flickable)
Example:
http://qt-project.org/wiki/How_to_make_QML_ListView_align_bottom-to-top
>listView
The main container
>delegate
Set the Style, Layout
>mode
Set the data
ListModel {
id: messageListModel
ListElement {
Title: "<STRONG><FONT color=#0000cc>AutoCAD Exchange</FONT></STRONG>" }
ListElement { Message: "Tom Jones invited 1 person to share <br><a href=\"TODO\">Floor_Plan.dwg </a>" } }
>Model/View Programming
Signals from the model inform the view about changes to the data held by the data source.
Signals from the view provide information about the user's interaction with the items being displayed.
Signals from the delegate are used during editing to tell the model and view about the state of the editor.
>QModelIndex
The QModelIndex class is used to locate data in a data model.
This class is used as an index into item models derived from QAbstractItemModel. QAbstractItemModel::createIndex()
>Sample
ListView {
id: messageListView
anchors {
top: midView.top
bottom: parent.bottom
left: parent.left
right: parent.right
}
model: notificationListModel //data
delegate: messageViewDelegate //style
}
---QMLDataModels End---