aboutsummaryrefslogtreecommitdiffstats
path: root/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@theqtcompany.com>2016-04-22 10:13:12 +0200
committerJ-P Nurmi <jpnurmi@qt.io>2016-04-26 14:48:09 +0000
commit3393180efbb186bee365deb730afa42e670a3187 (patch)
treec2a85b4fed00f0c27ba22ec5729429c360714e87 /src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
parent3d23801a874efff4821b7ee17f6ec098e22cf97a (diff)
Document how to create custom styles
Change-Id: I8abdb2133e1ff66b317e93fa65ff1faa5266410b Task-number: QTBUG-51785 Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc')
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc294
1 files changed, 294 insertions, 0 deletions
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
index f327c302..5b877736 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
@@ -34,6 +34,300 @@
provide a custom look and feel, the default QML implementation of each
item can be replaced with a custom one.
+ \section1 Customizing a Control
+
+ Sometimes you'll want to create a "one-off" look for a specific part of
+ your UI, and use a complete style everywhere else. Perhaps you're happy
+ with the style you're using, but there's a certain button that has some
+ special significance.
+
+ The first way to create this button is to simply define it in-place,
+ wherever it is needed. For example, perhaps you're not satisfied with the
+ default style's Button having square corners. To make them rounded, you
+ can override the \l {Control::}{background} item and set the radius
+ property of Rectangle:
+
+ \qml
+ import QtQuick 2.6
+ import QtQuick.Controls 2.0
+
+ ApplicationWindow {
+ width: 400
+ height: 400
+ visible: true
+
+ Button {
+ id: button
+ text: "A Special Button"
+ background: Rectangle {
+ implicitWidth: 100
+ implicitHeight: 40
+ color: button.down ? "#d6d6d6" : "#f6f6f6"
+ border.color: "#26282a"
+ border.width: 1
+ radius: 4
+ }
+ }
+ }
+ \endqml
+
+ The second way to create the button is good if you plan to use your rounded
+ button in several places. It involves moving the code into its own QML file
+ within your project.
+
+ For this approach, we'll copy the background code from the default style's
+ \c Button.qml. This file can be found in the following path in your Qt
+ installation:
+
+ \c {$QTDIR/qml/QtQuick/Controls.2/Button.qml}
+
+ After doing that, we'll simply add the following line:
+
+ \qml
+ radius: 4
+ \endqml
+
+ To avoid confusion with the controls in the
+ module itself, we'll call the file \c MyButton.qml. To use the control in
+ your application, refer to it by its filename:
+
+ \qml
+ import QtQuick.Controls 2.0
+
+ ApplicationWindow {
+ MyButton {
+ text: qsTr("A Special Button")
+ }
+ }
+ \endqml
+
+ The third way to create the button is a bit more structured, both in terms
+ of where the file sits in the file system and how it is used in QML. First,
+ copy an existing file as you did above, but this time, put it into a
+ subfolder in your project named (for example) \c controls. To use the
+ control, first import the folder into a namespace:
+
+ \qml
+ import QtQuick.Controls 2.0
+ import "controls" as MyControls
+
+ ApplicationWindow {
+ MyControls.Button {
+ text: qsTr("A Special Button")
+ }
+ }
+ \endqml
+
+ As you now have the \c MyControls namespace, you can name the controls after
+ their actual counterparts in the Qt Quick Controls 2 module. You can repeat
+ this process for any control that you wish to add.
+
+ \section1 Creating a Custom Style
+
+ There are several ways to go about creating your own styles. Below, we'll
+ explain the various approaches.
+
+ \section2 Definition of a Style
+
+ In Qt Quick Controls 2, a style is essentially an interchangeable set of
+ QML files within a single directory. There are two requirements for a style
+ to be \l {Using Styles in Qt Quick Controls 2}{usable}:
+
+ \list
+ \li At least one QML file whose name matches a control (for example,
+ \c Button.qml) must exist.
+
+ The Default style will be used for any controls that aren't implemented.
+ \li The files must be in a directory in the filesystem or in the
+ \l {The Qt Resource System}{resource system}.
+
+ For example, these are all valid paths to a style:
+
+ \list
+ \li \c {./myapp -style /home/absolute/path/to/my/style}
+ \li \c {./myapp -style :/mystyle}
+ \li \c {./myapp -style relative/path/to/my/style}
+ \li \c {./myapp -style MyStyle}
+ \endlist
+
+ The third and fourth paths will be looked up within the QML engine's import path
+ list. This is the same as what happens when you pass \c Material as the style,
+ for example.
+ \endlist
+
+ What this means is that you can implement as many controls as you like for
+ your custom style, and place them almost anywhere. It also allows users to
+ create their own styles for your application.
+
+ \section2 Style-specific C++ Extensions
+
+ Sometimes you may need to use C++ to extend your custom style. There are two
+ ways to expose such types to QML:
+
+ \list
+ \li If the style that uses the type is the only style used by an application,
+ it's enough to register it with the QML engine via qmlRegisterType():
+
+ \code
+ qmlRegisterType<ACoolCppItem>("MyApp", 1, 0, "ACoolItem");
+ \endcode
+
+ See \l {Using C++ Data From QML} for more information about this.
+ \li If the style that uses the type is one of many styles used by an
+ application, it may be better to only register it when necessary. This
+ is the point at which it would make sense to implement your own
+ \l {Creating C++ Plugins for QML}{QML plugin}.
+
+ Using a plugin as part of your style is not that much different from
+ using a set of QML files. The only difference is that the plugin and
+ its \c qmldir file must be present in the same directory as the QML
+ files.
+ \endlist
+
+ \section3 Attached properties
+
+ It is common for a style to have certain properties or attributes that
+ apply to all controls. \l {Attached Properties and Attached Signal
+ Handlers}{Attached properties} are a great way of extending an item in QML
+ without having to modify any existing C++ belonging to that item. For
+ example, both the \l {Material Style}{Material} and \l {Universal
+ Style}{Universal} styles have an attached theme property that controls
+ whether an item and its children will be rendered in a light or dark theme.
+
+ As an example, let's add an attached property that controls elevation. Our
+ style will illustrate the elevation with a drop shadow; the higher the
+ elevation, the larger the shadow.
+
+ The first step is to add a C++ type that stores the elevation. Since the
+ type will be used for every control supported by our style, and because we
+ may wish to add other attached properties later on, we'll call it
+ MyStyle. Here is \c MyStyle.h:
+
+ \code
+ #ifndef MYSTYLE_H
+ #define MYSTYLE_H
+
+ #include <QObject>
+ #include <QtQml>
+
+ class MyStyle : public QObject
+ {
+ Q_OBJECT
+ Q_PROPERTY(int elevation READ elevation WRITE setElevation NOTIFY elevationChanged)
+
+ public:
+ explicit MyStyle(QObject *parent = nullptr);
+
+ static MyStyle *qmlAttachedProperties(QObject *object);
+
+ int elevation() const;
+ void setElevation(int elevation);
+
+ signals:
+ void elevationChanged();
+
+ private:
+ int m_elevation;
+ };
+
+ QML_DECLARE_TYPEINFO(MyStyle, QML_HAS_ATTACHED_PROPERTIES)
+
+ #endif // MYSTYLE_H
+ \endcode
+
+ \c MyStyle.cpp:
+
+ \code
+ #include "mystyle.h"
+
+ MyStyle::MyStyle(QObject *parent) :
+ QObject(parent),
+ m_elevation(0)
+ {
+ }
+
+ MyStyle *MyStyle::qmlAttachedProperties(QObject *object)
+ {
+ return new MyStyle(object);
+ }
+
+ int MyStyle::elevation() const
+ {
+ return m_elevation;
+ }
+
+ void MyStyle::setElevation(int elevation)
+ {
+ if (elevation == m_elevation)
+ return;
+
+ m_elevation = elevation;
+ emit elevationChanged();
+ }
+ \endcode
+
+ The \c MyStyle type is special in the sense that it shouldn't be
+ instantiated, but rather used for its attached properties. For that reason,
+ we register it in the following manner:
+
+ \code
+ qmlRegisterUncreatableType<MyStyle>("MyStyle", 1, 0, "MyStyle", "MyStyle is an attached property");
+ \endcode
+
+ We then copy the existing default Button style, and add the code for a drop
+ shadow (which was taken from the Material Button style). We modify that
+ slightly to ensure that we:
+
+ \list
+ \li Don't bother using the drop shadow when the elevation is \c 0
+ \li Change the shadow's color depending on whether or not the button has
+ focus
+ \li Make the size of the shadow depend on the elevation
+ \endlist
+
+ \qml
+ layer.enabled: control.enabled && control.MyStyle.elevation > 0
+ layer.effect: DropShadow {
+ verticalOffset: 1
+ color: control.activeKeyFocus ? "#330066ff" : "#aaaaaa"
+ samples: control.MyStyle.elevation
+ spread: 0.5
+ }
+ \endqml
+
+ With that in place, we can try out our new elevation feature:
+
+ \qml
+ import QtQuick 2.6
+ import QtQuick.Controls 2.0
+
+ import MyStyle 1.0
+
+ ApplicationWindow {
+ id: window
+ width: 400
+ height: 400
+ visible: true
+
+ Row {
+ spacing: 20
+ anchors.centerIn: parent
+
+ Button {
+ text: "Button 1"
+ }
+ Button {
+ text: "Button 2"
+ MyStyle.elevation: 10
+ }
+ }
+ }
+ \endqml
+
+ The end result:
+
+ \image qtquickcontrols2-customize-buttons.png
+
\section1 Customization Reference
The following snippets present the default implementations of various