aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc17
-rw-r--r--src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc69
-rw-r--r--src/imports/controls/qtquickcontrols2plugin.cpp61
-rw-r--r--src/quickcontrols2/qquickstyle.cpp3
-rw-r--r--src/quickcontrols2/qquickstyleplugin.cpp75
-rw-r--r--src/quickcontrols2/qquickstyleplugin_p.h2
6 files changed, 149 insertions, 78 deletions
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
index e1ddd1e3..956c2c9d 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-customize.qdoc
@@ -111,9 +111,9 @@
\section2 Definition of a Style
- In Qt Quick Controls, a style is essentially an interchangeable set of
- QML files within a single directory. There are four requirements for a style
- to be \l {Using Styles in Qt Quick Controls}{usable}:
+ In Qt Quick Controls, a style is essentially a set of QML files within a
+ single directory. There are four requirements for a style to be
+ \l {Using Styles in Qt Quick Controls}{usable}:
\list
\li At least one QML file whose name matches a control (for example,
@@ -134,6 +134,17 @@
Button 2.15 Button.qml
\endcode
+ If you're using \l {Compile-Time Style Selection}{compile-time style
+ selection}, the qmldir should also import the fallback style:
+
+ \badcode
+ # ...
+ import QtQuick.Controls.Basic auto
+ \endcode
+
+ This can also be done for \l {Run-Time Style Selection}{run-time style selection}
+ instead of using, for example, \l QQuickStyle::setFallbackStyle().
+
The directory structure for such a style looks like this:
\badcode
diff --git a/src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc b/src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc
index 29e73540..a26287fc 100644
--- a/src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc
+++ b/src/imports/controls/doc/src/qtquickcontrols2-styles.qdoc
@@ -69,23 +69,62 @@
\section1 Using Styles in Qt Quick Controls
- In order to run an application with a specific style, either configure the
- style using \l[CPP]{QQuickStyle} in C++, pass a command line argument, or set an
- environment variable. Alternatively, the preferred style and style-specific
- attributes can be specified in a configuration file.
+ There are two ways of using styles in Qt Quick Controls:
+ run-time style selection and compile-time style selection.
- The priority of these approaches follows the order they are listed below,
+ \section2 Compile-Time Style Selection
+
+ Compile-time style selection involves using QML imports to specify the
+ style. For example, to import the Material style:
+
+ \qml
+ import QtQuick.Controls.Material
+
+ ApplicationWindow {
+ // ...
+ }
+ \endqml
+
+ Notice that QtQuick.Controls (which is responsible for run-time style
+ selection) is not imported. The fallback style is specified by the qmldir
+ of the style:
+
+ \badcode
+ module QtQuick.Controls.Material
+ # ...
+ import QtQuick.Controls.Basic auto
+ \endcode
+
+ The benefit of compile-time style selection is that the QtQuick.Controls plugin
+ is not used and therefore does not need to be deployed with the application.
+
+ \section2 Run-Time Style Selection
+
+ Run-time style selection involves importing \c QtQuick.Controls:
+
+ \qml
+ import QtQuick.Controls
+ \endqml
+
+ The QtQuick.Controls plugin will import the style and fallback
+ style that were set at runtime via one of the following approaches:
+
+ \list
+ \li \l[CPP]{QQuickStyle::setStyle()}
+ \li The \c -style command line argument
+ \li The \c QT_QUICK_CONTROLS_STYLE environment variable
+ \li The \c qtquickcontrols2.conf configuration file
+ \endlist
+
+ The priority of these approaches follows the order they are listed,
from highest to lowest. That is, using \c QQuickStyle to set the style will
always take priority over using the command line argument, for example.
- \warning When resolving a given style name to an absolute path, \c QQuickStyle
- may search the root resource directory (\c {:}). Consequently, make sure
- that your resource directories are named differently than the names of the
- styles that your application supports. Otherwise, the styles may not load.
- For example, avoid naming a resource directory \c :/material
- (or \c {:/Material}) if the application supports the Material style.
+ The benefit of run-time style selection is that a single application binary
+ can support multiple styles, meaning that the end user can choose which
+ style to run the application with.
- \section2 Using QQuickStyle in C++
+ \section3 Using QQuickStyle in C++
\l[CPP]{QQuickStyle} provides C++ API for configuring a specific
style. The following example runs a Qt Quick Controls application
@@ -98,7 +137,7 @@
See the detailed description of \l[CPP]{QQuickStyle} for more
details.
- \section2 Command line argument
+ \section3 Command line argument
Passing a \c -style command line argument is the convenient way to test different
styles. It takes precedence over the other methods listed below. The following
@@ -108,7 +147,7 @@
./app -style material
\endcode
- \section2 Environment variable
+ \section3 Environment variable
Setting the \c QT_QUICK_CONTROLS_STYLE environment variable can be used to set
a system-wide style preference. It takes precedence over the configuration file
@@ -122,7 +161,7 @@
See \l {Supported Environment Variables in Qt Quick Controls} for the full list
of supported environment variables.
- \section2 Configuration file
+ \section3 Configuration file
Qt Quick Controls support a special configuration file, \c :/qtquickcontrols2.conf,
that is built into an application's resources.
diff --git a/src/imports/controls/qtquickcontrols2plugin.cpp b/src/imports/controls/qtquickcontrols2plugin.cpp
index 88fce5ca..2bd4047d 100644
--- a/src/imports/controls/qtquickcontrols2plugin.cpp
+++ b/src/imports/controls/qtquickcontrols2plugin.cpp
@@ -34,7 +34,6 @@
**
****************************************************************************/
-#include <QtCore/private/qfileselector_p.h>
#include <QtCore/qloggingcategory.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlextensionplugin.h>
@@ -45,7 +44,7 @@
QT_BEGIN_NAMESPACE
-Q_LOGGING_CATEGORY(lcQtQuickControlsStylePlugin, "qt.quick.controls.qtquickcontrols2plugin")
+Q_LOGGING_CATEGORY(lcQtQuickControls2Plugin, "qt.quick.controls.qtquickcontrols2plugin")
class QtQuickControls2Plugin : public QQmlExtensionPlugin
{
@@ -60,8 +59,6 @@ public:
void unregisterTypes() override;
private:
- QQuickTheme *createTheme(const QString &name);
-
// We store these because the style plugins can be unregistered before
// QtQuickControls2Plugin, and since QQuickStylePlugin calls QQuickStylePrivate::reset(),
// the style information can be lost when it comes time to call qmlUnregisterModuleImport().
@@ -110,24 +107,22 @@ QtQuickControls2Plugin::~QtQuickControls2Plugin()
void QtQuickControls2Plugin::registerTypes(const char *uri)
{
- qCDebug(lcQtQuickControlsStylePlugin) << "registerTypes() called with uri" << uri;
+ qCDebug(lcQtQuickControls2Plugin) << "registerTypes() called with uri" << uri;
// It's OK that the style is resolved more than once; some accessors like name() cause it to be called, for example.
QQuickStylePrivate::init();
const QString styleName = QQuickStylePrivate::effectiveStyleName(QQuickStyle::name());
const QString fallbackStyleName = QQuickStylePrivate::effectiveStyleName(QQuickStylePrivate::fallbackStyle());
- qCDebug(lcQtQuickControlsStylePlugin) << "style:" << QQuickStyle::name() << "effective style:" << styleName
+ qCDebug(lcQtQuickControls2Plugin) << "style:" << QQuickStyle::name() << "effective style:" << styleName
<< "fallback style:" << QQuickStylePrivate::fallbackStyle() << "effective fallback style:" << fallbackStyleName;
- createTheme(styleName);
-
// If the style is Basic, we don't need to register the fallback because the Basic style
// provides all controls. Also, if we didn't return early here, we can get an infinite import loop
// when the style is set to Basic.
if (styleName != fallbackStyleName && styleName != QLatin1String("Basic")) {
registeredFallbackStyleUri = ::fallbackStyleUri();
- qCDebug(lcQtQuickControlsStylePlugin) << "calling qmlRegisterModuleImport() to register fallback style with"
+ qCDebug(lcQtQuickControls2Plugin) << "calling qmlRegisterModuleImport() to register fallback style with"
<< " uri \"" << qtQuickControlsUri << "\" moduleMajor" << QQmlModuleImportModuleAny
<< "import" << registeredFallbackStyleUri << "importMajor" << QQmlModuleImportAuto;
// The fallback style must be a built-in style, so we match the version number.
@@ -141,19 +136,15 @@ void QtQuickControls2Plugin::registerTypes(const char *uri)
customStyle = QQuickStylePrivate::isCustomStyle();
registeredStyleUri = ::styleUri();
const int importMajor = !customStyle ? QQmlModuleImportAuto : QQmlModuleImportLatest;
- qCDebug(lcQtQuickControlsStylePlugin).nospace() << "calling qmlRegisterModuleImport() to register primary style with"
+ qCDebug(lcQtQuickControls2Plugin).nospace() << "calling qmlRegisterModuleImport() to register primary style with"
<< " uri \"" << qtQuickControlsUri << "\" moduleMajor " << importMajor
<< " import " << registeredStyleUri << " importMajor " << importMajor;
qmlRegisterModuleImport(qtQuickControlsUri, QQmlModuleImportModuleAny, registeredStyleUri.toUtf8().constData(), importMajor);
-
- const QString style = QQuickStyle::name();
- if (!style.isEmpty())
- QFileSelectorPrivate::addStatics(QStringList() << style);
}
void QtQuickControls2Plugin::unregisterTypes()
{
- qCDebug(lcQtQuickControlsStylePlugin) << "unregisterTypes() called";
+ qCDebug(lcQtQuickControls2Plugin) << "unregisterTypes() called";
if (!registeredFallbackStyleUri.isEmpty()) {
// We registered a fallback style, so now we need to unregister it.
@@ -166,46 +157,6 @@ void QtQuickControls2Plugin::unregisterTypes()
qmlUnregisterModuleImport(qtQuickControlsUri, QQmlModuleImportModuleAny, registeredStyleUri.toUtf8().constData(), importMajor);
customStyle = false;
registeredStyleUri.clear();
-
- QQuickThemePrivate::instance.reset();
- QQuickStylePrivate::reset();
-}
-
-/*!
- \internal
-
- Responsible for setting the font and palette settings that were specified in the
- qtquickcontrols2.conf file.
-
- Style-specific settings (e.g. Variant=Dense) are read in the constructor of the
- appropriate style plugin (e.g. QtQuickControls2MaterialStylePlugin).
-
- Implicit style-specific font and palette values are assigned in the relevant theme
- (e.g. QQuickMaterialTheme).
-*/
-QQuickTheme *QtQuickControls2Plugin::createTheme(const QString &name)
-{
- qCDebug(lcQtQuickControlsStylePlugin) << "creating QQuickTheme instance to be initialized by style-specific theme of" << name;
-
- QQuickTheme *theme = new QQuickTheme;
-#if QT_CONFIG(settings)
- QQuickThemePrivate *p = QQuickThemePrivate::get(theme);
- QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(name);
- if (settings) {
- p->defaultFont.reset(QQuickStylePrivate::readFont(settings));
- // Set the default font as the System scope, because that's what
- // QQuickControlPrivate::parentFont() uses as its fallback if no
- // parent item has a font explicitly set. QQuickControlPrivate::parentFont()
- // is used as the starting point for font inheritance/resolution.
- // The same goes for palettes below.
- theme->setFont(QQuickTheme::System, *p->defaultFont);
-
- p->defaultPalette.reset(QQuickStylePrivate::readPalette(settings));
- theme->setPalette(QQuickTheme::System, *p->defaultPalette);
- }
-#endif
- QQuickThemePrivate::instance.reset(theme);
- return theme;
}
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickstyle.cpp b/src/quickcontrols2/qquickstyle.cpp
index d5ded6c2..ca844c6f 100644
--- a/src/quickcontrols2/qquickstyle.cpp
+++ b/src/quickcontrols2/qquickstyle.cpp
@@ -91,6 +91,9 @@ Q_LOGGING_CATEGORY(lcQtQuickControlsStyle, "qt.quick.controls.style")
Qt Quick Controls. It is not possible to change the style after the QML
types have been registered.
+ \note QQuickStyle is not supported when using
+ \l {Compile-Time Style Selection}{compile-time style selection}.
+
To create your own custom style, see \l {Creating a Custom Style}. Custom
styles do not need to implement all controls. By default, the styling
system uses the \l {Basic style} as a fallback for controls that a custom
diff --git a/src/quickcontrols2/qquickstyleplugin.cpp b/src/quickcontrols2/qquickstyleplugin.cpp
index f211d4b0..730a8423 100644
--- a/src/quickcontrols2/qquickstyleplugin.cpp
+++ b/src/quickcontrols2/qquickstyleplugin.cpp
@@ -38,9 +38,11 @@
#include "qquickstyle_p.h"
#include "qquickstyleplugin_p.h"
+#include <QtCore/private/qfileselector_p.h>
#include <QtCore/qloggingcategory.h>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlfile.h>
+#include <QtQml/private/qqmlmetatype_p.h>
#include <QtQuickTemplates2/private/qquicktheme_p_p.h>
QT_BEGIN_NAMESPACE
@@ -60,25 +62,88 @@ void QQuickStylePlugin::registerTypes(const char *uri)
{
qCDebug(lcStylePlugin).nospace() << "registerTypes called with uri " << uri << "; plugin name is " << name();
+ const QTypeRevision latestControlsRevision = QQmlMetaType::latestModuleVersion(QLatin1String("QtQuick.Controls"));
+ QString styleName = QQuickStyle::name();
+ if (!latestControlsRevision.isValid() && styleName.isEmpty()) {
+ // The user hasn't imported QtQuick.Controls, nor set a style via the runtime methods.
+ qCDebug(lcStylePlugin).nospace() << uri << " imported before QtQuick.Controls; using compile-time style selection";
+ QQuickStyle::setStyle(name());
+ styleName = name();
+ }
+
+ // Even if this style plugin isn't for the style set by the user,
+ // we still want to create the theme object, because that function
+ // is also responsible for reading values from qtquickcontrols2.conf.
+ // So, even if a style doesn't have a QQuickTheme, it can still have
+ // values set for (e.g. fonts and palettes) in qtquickcontrols2.conf.
+ const QString effectiveCurrentStyleName = QQuickStylePrivate::effectiveStyleName(styleName);
auto theme = QQuickTheme::instance();
if (!theme) {
- qWarning() << "QtQuick.Controls must be imported before importing" << baseUrl().toString();
- return;
+ qCDebug(lcStylePlugin) << "creating theme";
+ theme = createTheme(effectiveCurrentStyleName);
}
- if (name() != QQuickStyle::name()) {
+ if (name() != effectiveCurrentStyleName) {
qCDebug(lcStylePlugin).nospace() << "theme does not belong to current style ("
- << QQuickStyle::name() << "); not calling initializeTheme()";
+ << effectiveCurrentStyleName << "); not calling initializeTheme()";
return;
}
- qCDebug(lcStylePlugin) << "theme has not been initialized; calling initializeTheme()";
+ qCDebug(lcStylePlugin) << "theme has not yet been initialized; calling initializeTheme()";
initializeTheme(theme);
+
+ if (!styleName.isEmpty())
+ QFileSelectorPrivate::addStatics(QStringList() << styleName);
}
void QQuickStylePlugin::unregisterTypes()
{
qCDebug(lcStylePlugin) << "unregisterTypes called; plugin name is" << name();
+ if (!QQuickThemePrivate::instance)
+ return;
+
+ // Not every style has a plugin - some styles are QML-only. So, we clean this
+ // stuff up when the first style plugin is unregistered rather than when the
+ // plugin for the current style is unregistered.
+ QQuickThemePrivate::instance.reset();
+ QQuickStylePrivate::reset();
+}
+
+/*!
+ \internal
+
+ Responsible for setting the font and palette settings that were specified in the
+ qtquickcontrols2.conf file.
+
+ Style-specific settings (e.g. Variant=Dense) are read in the constructor of the
+ appropriate style plugin (e.g. QtQuickControls2MaterialStylePlugin).
+
+ Implicit style-specific font and palette values are assigned in the relevant theme
+ (e.g. QQuickMaterialTheme).
+*/
+QQuickTheme *QQuickStylePlugin::createTheme(const QString &name)
+{
+ qCDebug(lcStylePlugin) << "creating QQuickTheme instance to be initialized by style-specific theme of" << name;
+
+ QQuickTheme *theme = new QQuickTheme;
+#if QT_CONFIG(settings)
+ QQuickThemePrivate *p = QQuickThemePrivate::get(theme);
+ QSharedPointer<QSettings> settings = QQuickStylePrivate::settings(name);
+ if (settings) {
+ p->defaultFont.reset(QQuickStylePrivate::readFont(settings));
+ // Set the default font as the System scope, because that's what
+ // QQuickControlPrivate::parentFont() uses as its fallback if no
+ // parent item has a font explicitly set. QQuickControlPrivate::parentFont()
+ // is used as the starting point for font inheritance/resolution.
+ // The same goes for palettes below.
+ theme->setFont(QQuickTheme::System, *p->defaultFont);
+
+ p->defaultPalette.reset(QQuickStylePrivate::readPalette(settings));
+ theme->setPalette(QQuickTheme::System, *p->defaultPalette);
+ }
+#endif
+ QQuickThemePrivate::instance.reset(theme);
+ return theme;
}
QT_END_NAMESPACE
diff --git a/src/quickcontrols2/qquickstyleplugin_p.h b/src/quickcontrols2/qquickstyleplugin_p.h
index 1a941aa7..0cc793a2 100644
--- a/src/quickcontrols2/qquickstyleplugin_p.h
+++ b/src/quickcontrols2/qquickstyleplugin_p.h
@@ -70,6 +70,8 @@ public:
void unregisterTypes() override;
private:
+ QQuickTheme *createTheme(const QString &name);
+
Q_DISABLE_COPY(QQuickStylePlugin)
};