Material theme doesn't seem to work in QML - qt

I have a simple QML with an ApplicationWindow, RowLayout and a bunch of Buttons inside. I have applied the Qt Quick Controls 2 Material theme as per the docs, but nothing changed. What's wrong?
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
import QtQuick.Layouts 1.3
ApplicationWindow {
Material.theme: Material.Dark
Material.accent: Material.Orange
id: window
visible: true
RowLayout {
anchors.horizontalCenter: window.horizontalCenter
anchors.bottomMargin: 32
Button {
text: "A"
}
Button {
text: "B"
}
Button {
text: "C"
}
}
}

Importing QtQuick.Controls.Material 2.0 and setting some Material specific properties do not apply the Material theme. They will be used if the theme is set using one of the methods described here:
http://doc.qt.io/qt-5/qtquickcontrols2-styles.html

Related

Custom QML Quick 2 Control with TabBar Inside

I am creating a custom QML Quick 2 TabBar control in Qt 5.15. If I make a simple control (CustomTabBarSimple.qml) as
import QtQuick 2.0
import QtQuick.Controls 2.15
TabBar {
}
Then I can use it with
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
Window {
visible: true
width: 640; height: 480
color:"silver"
CustomTabBarSimple
{
id:bar
TabButton { text:"Button1" }
TabButton { text:"Button2" }
}
StackLayout {
anchors.top: bar.bottom
currentIndex: bar.currentIndex
Text {text: "First Stack"}
Text {text: "Second Stack"}
}
}
But if instead I wrap the TabBar in another control like this is no longer functions:
import QtQuick 2.0
import QtQuick.Controls 2.15
Rectangle
{
default property alias contents: bar.data
width: 300; height:50
color: "red"
TabBar {
id: bar
}
}
You can see I tried to use default property alias contents: bar.data to put the TabButton inside the custom control's TabBar but it appears that the TabBar no longer organizes the buttons properly and they no longer change the currentIndex when clicked---likely because the data field is overwriting critical elements.
Is it possible to inject the TabButton into the proper place using a default alias? Second, how would I be able to discover this for myself from the documentation?
There's two problems with your code:
You're trying to access currentIndex from the TabBar, but you're not exposing that property in your CustomTabBarSimple. You can fix that by adding this:
property alias currentIndex: bar.currentIndex
The list of TabButtons are not direct children of the TabBar. TabBar is derived from a Container, which has a list of child objects in contentData. You can read about that here.
default property alias contents: bar.contentData

QML Dialog positioning in ApplicationWindow

I am finding it impossible to position a Dialog central to my ApplicationWindow in QT 5.12
import QtQuick 2.7
import QtQuick.Controls 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
id:mainApplicationWindow
visible: true
height: 500
width: 500
Item {
anchors.centerIn: parent
MainWindowMessageDialog{
id: messageDialog
}
}
Component.onCompleted: {
messageDialog.open()
}
}
With MainWindowMessageDialog.qml
import QtQuick 2.0
import QtQuick.Dialogs 1.2
Dialog {
title: "There seems to be a problem"
standardButtons: StandardButton.Ok
onAccepted: {
this.close()
}
}
Gives me the image below. I've tried adding a fixed z position but nothing seems to shift the Dialog downwards into the window. I've tried MainWindowMessageDialog on its own outside of an Item. Nothing seems to shift it? Am I missing something?
This turned out to be an issue of modality.
https://bugreports.qt.io/browse/QTBUG-82737?jql=text%20~%20%22MessageDialog%22
Adding
modality: Qt.ApplicationModal
Did the trick

Can't set text field to fill width in QML

I am following this tutorial on YouTube and the person sets the TextField to fill the width of the RowLayout. However, it doesn't seem to work for me. I tried using Layout.fillWidth on the CheckBox and it seems to work perfectly fine but it doesn't seem to want to work on the TextField. Here is my code:
main.qml:
import QtQuick 2.9
import QtQuick.Controls 2.2
ApplicationWindow
{
visible: true;
width: 640;
height: 480;
title: qsTr("Tabs");
ToDoList
{
anchors.centerIn: parent;
}
}
ToDoList.qml:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Frame
{
ListView
{
// Using implicit width and height allows the frame to automatically scale to the size of the list view
implicitWidth: 250
implicitHeight: 250
clip: true
model: 100
delegate: RowLayout {
width: parent.width
CheckBox {}
TextField
{
Layout.fillWidth: true
}
}
}
}
Here is a screenshot of what mine looks like
What did I do wrong?
I don't know if this has anything to do with it but I made a "Qt Quick Application - Swipe" instead of "Qt Quick Controls 2 Application" as that option wasn't available to me. Thanks in advance for any help.
Edit: I have written step by step instructions to replicate the issue below.
File > New File or Project
From the new window make sure "Application" is selected then click "Qt Quick Application - Swipe" and press "Choose"
Set any name for the project and click "Next"
Set the build system to "qmake" and click "Next"
Set the minimal required Qt version to "Qt 5.9" and the Qt quick controls style to "Material Dark" and click "Next"
Select the "Desktop Qt 5.12.0 MSVC2017 64bit" as the kit and click "Next"
Set the options to have no version control and click "Finish"
Delete "Page1Form.ui.qml" and "Page2Form.ui.qml" from the "Projects" pane
Replace the contents of "main.qml" with:
import QtQuick 2.9
import QtQuick.Controls 2.2
ApplicationWindow
{
visible: true;
width: 640;
height: 480;
title: qsTr("Tabs");
ToDoList
{
anchors.centerIn: parent;
}
}
Right click on the root project file and click "Add New"
From the new window make sure "Qt" is selected then click "QML File (Qt Quick 2)" and press "Choose"
Name the file "ToDoList" and click "Next"
Add to project "qml.qrc Prefix: /" then set the options to have no version control and click "Finish"
Replace the contents of "ToDoList.qml" with:
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
Frame
{
ListView
{
// Using implicit width and height allows the frame to automatically scale to the size of the list view
implicitWidth: 250
implicitHeight: 250
clip: true
model: 100
delegate: RowLayout {
width: parent.width
CheckBox {}
TextField
{
Layout.fillWidth: true
}
}
}
}
Run the project
The width is set properly. The problem is with TextField style. You may check it by setting background like
TextField
{
Layout.fillWidth: true
background: Rectangle {
color: "red"
}
}
Or just start typing into those fields with and without Layout.fillWidth: true

QML - Cannot assign to non-existent property "style"

I'm using Qt 5.10.1 with Qt Creator 4.5.1 and the style property is never available in elements.
For example, as shown here ButtonStyle QML Type , I would like to do:
Button {
text: "A button"
style: ButtonStyle {...}
}
But, I get the error:
Cannot assign to non-existent property "style"
I tried with a rectangle, progressbar and I get the same error.
Edit #1:
I do have all these imports. If the import was missing, I would get the error on ButtonStyle , but the error is on style.
import QtQuick 2.2
import QtQuick.Controls 2.3
import QtQuick.Dialogs 1.0
import QtGraphicalEffects 1.0
import QtQuick.Shapes 1.0
import QtQuick.Layouts 1.3
import QtQuick.Controls.Styles 1.4
There are 2 types of Buttons in QML:
Button Qt Quick Controls 2: https://doc.qt.io/qt-5.10/qml-qtquick-controls2-button.html
Button Qt Quick Controls: http://doc.qt.io/qt-5/qml-qtquick-controls-button.html
In your case, you are importing the Qt QuickControls 2 Button: import QtQuick.Controls 2.3, and that Button does not have the style attribute.
If you need to use the style you must import:
import QtQuick.Controls 1.4
instead of:
import QtQuick.Controls 2.3
If you are using items from Qt Quick Controls and Qt Quick Controls 2 you could separate them using a namespace:
import QtQuick.Controls 2.3 as QQC2
import QtQuick.Controls 1.4 as QQC1
QQC1.Button {
text: "A button"
style: ButtonStyle {...}
}
QQC2.another_item_of_Qt_Quick_Controls2{
}
You can customize Qt Quick Controls 2 button by modifying its two visual items of background and content item:
https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-button
import QtQuick 2.12
import QtQuick.Controls 2.12
Button {
id: control
text: qsTr("Button")
contentItem: Text {
text: control.text
font: control.font
opacity: enabled ? 1.0 : 0.3
color: control.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 40
opacity: enabled ? 1 : 0.3
border.color: control.down ? "#17a81a" : "#21be2b"
border.width: 1
radius: 2
}
}
Make sure importing QtQuick.Controls.Styles
import QtQuick.Controls.Styles 1.4
Button {
text: "A button"
style: ButtonStyle {...}
}

QML Button exclusiveGroup property?

I'm unable to assign ExclusiveGroup to my checkable buttons.
ExclusiveGroup {
id: group
onCurrentChanged: {
if(current != null) {
console.info("button checked...no!")
current = null
//current.checked = false <--- also this
}
}
}
Column {
width: parent.width
spacing: 0
Button {
id: btnScan
flat: true
text: qsTr("But1")
width: parent.width
checkable: true
exclusiveGroup: group
}
Button {
id: btnWhiteList
flat: true
text: qsTr("But2")
width: parent.width
checkable: true
exclusiveGroup: group
}
}
The documentation states clearly that Button does have exclusiveGroup property http://doc.qt.io/qt-5/qml-qtquick-controls-button.html#exclusiveGroup-prop. However, when I run the example, I get this error:
qrc:/main.qml:48 Cannot assign to non-existent property "exclusiveGroup"
Hovering mouse over "exclusiveGroup" makes a tooltip show up saying: "Invalid property name exclusiveGroup".
I have Qt 5.9.1 installed. Here's my import statements:
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
import QtQuick.Controls.Material 2.2
What am I doing wrong?
Thanks
The reason for your problem is this:
import QtQuick.Controls 1.4
import QtQuick.Controls 2.0
You have a Button in both, but they have a different API.
So at first you import the Button from QtQuick.Controls 1.4. Then you import the Button from QtQuick.Controls 2.0. As QML doesn't know, which one you want to use, it will take the one, you imported the last. If you want to be more specific, on which Button you want to use, you can use named imports
import QtQuick.Controls 1.4 as OldCtrl
import QtQuick.Controls 2.0 as NewCtrl
Then you can use Buttons from both versions as you like:
OldCtrl.Button { // from the QtQuick.Controls 1.4 }
NewCtrl.Button { // from the QtQuick.Controls 2.0 }
The documentation you quote is for QtQuick.Controls 1.x, and from there is the imported ExclusiveGroup. So you are trying to mix things from two libraries, that wont work together.
See ButtonGroup for a similar solution for QtQuick.Controls 2.x
For more on the differences and usecases of the both sets of controls read:
http://blog.qt.io/blog/2016/06/10/qt-quick-controls-2-0-a-new-beginning/
https://doc.qt.io/qt-5/qtquickcontrols2-differences.html

Resources