QML: Change ToolBar color / one style property only
-
Hi,
I'm writing a simple Android/IOS app using qml, but for the live of me I can't figure out, if there is a way to
change the toolbar background color without effecting any other element of the style.What I'm currently at is this:
import QtQuick 2.4 import QtQuick.Controls 1.3 import QtQuick.Controls.Styles 1.4 ApplicationWindow { title: "HAL 9000" height: 960 width: 600 color: "white" visible: true menuBar: MenuBar { Menu { title: "Views" [...] } } toolBar: ToolBar { [...] style: ToolBarStyle { panel: Rectangle { color: "blue" } } } }
While this does change the color correctly, the problem is that the menu-botton is invisible/non-existant since my ToolBarStyle does not contain anything for its menuButton property.
Since I only want to change the background color (of the toolbar) without having to "reimplement" the default implementation of the menuButton property, I do wonder if there is a way to simple change color, eg. via toolBar.style.panel.color: "pink"?Any help would be greatly appreciated...
-
Hi Thomas,
I've also run into this problem. Unfortunately, I do not believe there is a way to change only a part of an element's style. In my experience, the moment you edit part of an element's style, the entire default style is thrown out the window.
It can be very frustrating.
Unless someone can hopefully prove me wrong, you'll need to restyle the entire toolbar, including the menuButton. You can access the menuButton's style data to tell Qt to draw it differently depending on if it is pressed, hovered, or in active focus. Here is some documentation.
Let me know if you need help setting up the style.
-Brian
-
Hi Brian,
thank you for your reply. I did some further research/digging and found 3 possible solutions so far:
-
Completely reimplement the ToolBarStyle. The disadvantage is I'd also have to re-implement/copy all the logic/smartness that is currently handeled by the default qml implementation. (I REALLY dislike duplicate code :P)
-
ToolBarStyle actually uses/loads its style from the android-system (see AndroidStyle.qml, qquickandroidstyle.cpp, qquickandroid9patch.cpp). I can use/modify this behavior by editing AndroidStyle.qml like this for example:
(Currently I simply overwrite the Qt src file, long-term I need to look into replacing the default one by including/importing this code from inside my project)// AndroidStyle.qml pragma Singleton import QtQml 2.0 import QtQuick.Controls.Styles.Android 1.0 AndroidStyleBase { function getStyle(data) { // This json is loaded from your device via qquickandroidstyle.cpp var json = JSON.parse(data); json.actionBarStyle.ActionBar_backgroundStacked = { "type": "color", "color": 4278190335 }; // Color is AARRGGBB (HEX) in (UNSIGNED-INT) return json; } readonly property var styleDef: getStyle(data) }
-
Change the activity-theme via the AndroidManifest.xml. This works since Qt/QML mimicks the native look as described above...
The only problem I have with this, it works flawlessly with Theme, Theme.Holo, Theme.Holo.Light, but I can't get it working with custom Themes, eg.<!-- android/res/values/themes.xml --> <?xml version="1.0" encoding="utf-8"?> <resources> <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo"> <item name="android:actionBarStyle">@style/MyActionBar</item> </style> <style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar"> <item name="android:background">#ffff0000</item> <item name="android:backgroundStacked">#ffff0000</item> <item name="android:backgroundSplit">#ffff0000</item> </style> </resources>
And inside my AndroidManifest.xml:
[...] <application android:theme="@style/CustomActionBarTheme" ... [...]
This does show a red-colored ToolBar (my guess the one created by the activity) at startup which is shortly thereafter overdrawn by qml using its default android theme...
-
-
@Thomas Be aware of modifying the Qt sources. Its ok if you donot publish your product with these modifcations. For personal use all is fine.
-
I have a similar problem too. I want to change the font size and I get a fallback base style.
I've already reported a bug against Qt. Maybe we could find another workaround in the meantime.
All the android styling seems done by the AndroidStyle singleton object coming from QtQuick.Controls.Styles.Android 1.0 module.
They do, for example
Style { readonly property Button control: __control property Component panel: Item { id: panel readonly property var styleDef: control.checkable ? AndroidStyle.styleDef.buttonStyleToggle : AndroidStyle.styleDef.buttonStyle // some more code }
see ButtonStyle.qml
But, if we look further, styleDef seems specific to the Android drawables, see this commit
And the Android Button.qml seems to use something like this for setting the style
style: Settings.styleComponent(Settings.style, "ButtonStyle.qml", button)
But I don't know where the settings come from
See Button.qml
Do you have any idea what to do with it? I don't see any other option that copying the Android Styles tree and adapting it to our needs. But it's awful.