Bounce effect in a ComboBox QML - qt

I am trying to change the color of the background of the comboBox when pulling till you have a "bounce effect". Cause my background color in the comboBox is black but on the bounce effect the background of the background is white.
If it's not possible I would at least want to be able to desactivate this effect "bouncing effect".
I tried as describe here but it didn't work.
Thanks in advance for your help.

The white background you are seeing is from the popup property embedded in the ComboBox, specifically its background.color. To customize this, the documentation recommends you re-implement the entire popup as well as its ListView contentItem. Re-implementation of this type can be quite painful as you must re-implement all behaviors as well as visual characteristics. I find this to be overkill when you only want to tweak a property or two that already exists.
An easier way is to set the properties at runtime. Here is a working example that shows how to modify your "bounce effect" color as well as modify effect itself:
ComboBox {
id: comboBox
model: ["first", "second", "third"]
delegate: Rectangle { // My remake of your black-background delegates
color: "black"
implicitHeight: 20
implicitWidth: comboBox.width
Text {
anchors {
centerIn: parent
}
text: modelData
color: "lime"
}
}
// At runtime, reach into the comboBox.popup and set the background and boundsBehavior:
Component.onCompleted: {
comboBox.popup.background.color = "black" // Set "bounce" background color to black
comboBox.popup.contentItem.boundsBehavior = Flickable.StopAtBounds // Change/stop "bounce" behavior
}
}

Related

Change ListView's current index background color and not override other "states"

My Qt Quick Control 2 app is using Material Dark Theme. I would like to change background color of selected item in ListView. I know that I can do this in item delegate:
SwipeDelegate {
id: delegate
checkable: true
spacing: 0
width: parent.width
background: Rectangle {
color: index===currentIndex ? "red" : "transparent"
}
But with change above I'm losing defaults padding etc and also Material's radial animation on press and hold state is missing too. Is it possible to just change color only of selected item and keep original behavior for other states of item? Seems that I must reimplement missing things by my self
Maybe you should consider to implement highlight. The following worked for me:
ListView {
// ... Your stuff ...
highlight: Rectangle { color: "lightsteelblue"; }
focus: true
}

What is the correct understanding about ScrollBar syntax in QtQuick/QML?

Recently, I used a Scrollbar with a TableView. I referred to
QML documentation for ScrollBar and I can see an example:
Flickable {
focus: true
Keys.onUpPressed: scrollBar.decrease()
Keys.onDownPressed: scrollBar.increase()
ScrollBar.vertical: ScrollBar { id: scrollBar }
}
I thought that ScrollBar.vertical is a bool variant, but why there is an object ScrollBar { id: scrollBar } after colon?
Is there any documentation about this syntax?
What is the difference between using
ScrollBar.vertical: ScrollBar { id: scrollBar }
and
ScrollBar { id: scrollBar; orientation: Qt.Vertical }
The same confusion came to me with the code below:
Flickable {
anchors.fill: parent
contentWidth: parent.width * 2
contentHeight: parent.height * 2
ScrollBar.horizontal: ScrollBar { id: hbar; active: vbar.active }
ScrollBar.vertical: ScrollBar { id: vbar; active: hbar.active }
}
On the line anchors.fill: parent, anchors is lower-case.
I thought that ScrollBar.vertical is a bool variant, but why there is an object ScrollBar { id: scrollBar } after the colon?
The answer is simply because ScrollBar.vertical is neither a bool nor a variant but has a type of ScrollBar. This is stated in the documentation.
ScrollBar.vertical : ScrollBar
This property attaches a vertical scroll bar to a Flickable.
Flickable {
contentHeight: 2000
ScrollBar.vertical: ScrollBar { }
}
Note the subheader tells us the type after the colon: ScrollBar.
Is there any documentation about this syntax?
Yes there is. I copied the above from this page.
What is the difference between using [...]
I'll walk through each confusing line of code and label each one with its name.
// Attached Property
ScrollBar.vertical: ScrollBar { id: scrollBar }
// Child Object
ScrollBar { id: scrollBar; orientation: Qt.Vertical }
// Grouped Property
anchors.fill: parent
Let's go through these one-by-one.
Attached Properties
Attached properties [...] are mechanisms that enable objects to be annotated with extra properties or signal handlers that are otherwise unavailable to the object. In particular, they allow objects to access properties or signals that are specifically relevant to the individual object.
References to attached properties [...] take the following syntax form:
<AttachingType>.<propertyName>
For example, the ListView type has an attached property ListView.isCurrentItem that is available to each delegate object in a ListView. This can be used by each individual delegate object to determine whether it is the currently selected item in the view:
import QtQuick 2.0
ListView {
width: 240; height: 320
model: 3
delegate: Rectangle {
width: 100; height: 30
color: ListView.isCurrentItem ? "red" : "yellow"
}
}
In this case, the name of the attaching type is ListView and the property in question is isCurrentItem, hence the attached property is referred to as ListView.isCurrentItem.
(source)
In our particular case, ScrollBar is the attaching type and vertical is the property.
Keep in mind that there are several differences between ListView.isCurrentItem and ScrollBar.vertical. The former is of type bool while the latter is of type ScrollBar. Additionally, the former is a read-only property, meaning that we can't assign or change it. On the other hand, you can assign to ScrollBar.vertical.
If ListView.isCurrentItem wasn't read-only, we could've assigned it like we did with ScrollBar.vertical.
delegate: Rectangle {
ListView.isCurrentItem: true
}
But since it is read-only, this raises an error.
Child Objects
This is QML basics right here. Here's an example:
ApplicationWindow {
visible: true
width: 800; height: 600
// child object of ApplicationWindow
Rectangle {
width: 200; height: 200
color: "red"
// child object of Rectangle
Text { text: "Hello World" }
}
// child object of ApplicationWindow
Rectangle {
x: 400
width: 200; height: 200
color: "blue"
}
}
Looking back at ScrollBar:
Flickable {
ScrollBar { id: scrollBar; orientation: Qt.Vertical }
}
This will instantiate a child object ScrollBar but that's it. No added functionality.
Grouped Properties
In some cases properties contain a logical group of sub-property attributes. These sub-property attributes can be assigned to using either the dot notation or group notation.
For example, the Text type has a font group property. Below, the first Text object initializes its font values using dot notation, while the second uses group notation:
Text {
// dot notation
font.pixelSize: 12
font.b: true
}
Text {
// group notation
font { pixelSize: 12; b: true }
}
(source)
Another common example of a grouped property is anchors (as you may have noted).
Don't let the dot notation confuse you. Try to spot a generic difference between the two properties below:
anchors.top
ScrollBar.vertical
The important distinction to make is that properties must begin with a lower-case letter whereas QML types begin with an upper-case letter. With this in mind, we can see that anchors is clearly a property while ScrollBar is a type.
With those out of the way, I think we can try to address one more issue.
Why use attached properties instead of defining ScrollBar as a child object?
Because of better automation. From documentation:
When ScrollBar is attached vertically or horizontally to a Flickable, its geometry and the following properties are automatically set and updated as appropriate:
orientation
position
size
active
An attached ScrollBar re-parents itself to the target Flickable. A vertically attached ScrollBar resizes itself to the height of the Flickable, and positions itself to either side of it based on the layout direction. A horizontally attached ScrollBar resizes itself to the width of the Flickable, and positions itself to the bottom.
(source)
This allows you to focus on other things, instead of worrying about the position of the scrollbar.
But sure, instantiating ScrollBar as a child object (non-attached) also has it merits.
It is possible to create an instance of ScrollBar without using the attached property API. This is useful when the behavior of the attached scroll bar is not sufficient or a Flickable is not in use. [...]
When using a non-attached ScrollBar, the following must be done manually:
Layout the scroll bar (with the x and y or anchor properties, for example).
Set the size and position properties to determine the size and position of the scroll bar in relation to the scrolled item.
Set the active property to determine when the scroll bar will be visible.
(source)

Set backgrond of QML TreeView

I want to set a background colour for my tree view but cannot find a way.
Say I have the following
Rectangle {
width: 800
height: 800
anchors.fill: parent
TreeView {
id: view
model: theModel
}
}
What do I need to set a background color?
Setting a color on the parent does not work and I cannot see how to use TreeViewStyle to do this.
You can add the property backgroundVisible: false (and alternatingRowColors: false if needed).
The delegate is not affected by this property. You may need to define a new one without a background.

Add background and font colour to a button with material design

I am trying to design a login form with a material design on Qt which should look something like this:
However I can't figure out how to add colour to the button in QML and change the font colour of the button text. This is what I have got so far:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
Item {
property alias login: login
Pane {
id: pane
x: 144
y: 117
width: 353
height: 246
clip: false
font.strikeout: false
background: Rectangle {
color: "#ffffff"
}
ColumnLayout {
id: columnLayout
x: 139
y: -158
anchors.fill: parent
TextField {
id: username
Layout.fillWidth: true
placeholderText: qsTr("Username")
}
TextField {
id: password
Layout.fillWidth: true
placeholderText: qsTr("Password")
}
Button {
id: login
text: qsTr("Login")
spacing: -2
font.capitalization: Font.MixedCase
Layout.fillWidth: true
highlighted: false
// background: Rectangle {
// implicitWidth: 100
// implicitHeight: 40
// color: button.down ? "#d6d6d6" : "#f6f6f6"
// border.color: "#26282a"
// border.width: 1
// radius: 4
// }
}
}
}
}
As you can see (in the commented code) I tried to add colour using Rectangle with the background property but this removes the button features like shadow, highlight, darken on click and so on. Is there a simple way to accomplish this?
For reference here is the output of my code:
In order to theme a Material controls, you have to use the Material attached properties
In your case you want to use Material.background :
import QtQuick.Controls.Material 2.2
// ...
Button {
id: login
text: qsTr("Login")
Layout.fillWidth: true
Material.background: Material.Indigo
Material.foreground: "white"
}
Note that buttons should have upercased text, according to the material guidelines.
If you want to have a design that complies with the Google Materials design guidelines, the easiest way, is to use
QtQuick.Controls.Materials
To use them, it is sufficent to use any of the methods described here to activate them in your application. To try it out, I'd reccomend the command line argument. Just start your application with
-style material
If you want to have it fixed in your code, put it in the main.cpp:
QQuickStyle::setStyle("Material");
Note that the -style options is the very same option defined here for widgets and desktop os styles. Despite this quick styles and widget styles are totally different things and you cannot apply the former to the latter and vice versa. Widget
If now you already use the Material-style, but are not contempt with it and desire to change some of the definitions for selected controls, you can import
import QtQuick.Controls.Materials 2.x
where you need to adapt x to the most recent version installed. 0 is the right one for Qt5.7
Then you can alter specific aspects like
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
ApplicationWindow {
id: mainWindow
width: 800
height: 600
visible: true
Button {
id: login
text: qsTr("LOGIN")
Material.background: Material.Orange // Change the background
}
}
If you don't want to use the Material and only want to change a specific color of the Control you need to understand why it is not that easy to do, without messing it up.
I tried to add colour using Rectangle with the background property but this removes the button features like shadow, highlight, darken on click and so on. Is there a simple way to accomplish this?
You can't just change the color of the background, as there is not the color. There are various colors that are applied for different states. The expression might look like this:
color: (control.down ? 'darkgrey' : 'lightgrey')
So if you change the color to orange like this:
color: 'orange'
you messed up, as now the other state is not considered anymore.
Additionally, of course, you can't change the color of the background like background.color: 'green' from the beginning, as QML does not know about the property background.color. It expects an Item there, which has no color and the Rectangle is only created later. So what you need to do is
Be cautious to not override states
Wait until the property is available
example.qml
Button {
id: login
text: qsTr("LOGIN")
Binding {
target: login
property: "background.color"
value: 'red'
when: !login.pressed // Here comes the state
}
}
You can simply highlight a Button to make the button colorize its background in a style-independent way. The Material style fills the background with the accent color and makes the text light:
Button {
text: qsTr("Login")
highlighted: true
}
A highlighted Button is by far more efficient than a customized button. Customization should be done only if necessary. It is just a visual highlight. There can be multiple highlighted buttons. Highlighting a Button does not affect focus.

How to customize a QtQuick 2 component style while enable is false

When I set enabled property on a ComboBox for example, then it gets "greyed out". As far as I can tell it draws a layer above the component with a certain opacity so the original design is visible but becomes slightly faded. How can I tweak this effect?
I tried to change my components background color based on the enabled property's state, but that didn't help. For example I have set my background color to red, when the enabled property was false, but it didn't become red, it became more like a light red due to the overlay what I was describing above.
A simple code example:
ComboBox {
id: control
enabled: false
model: ["First", "Second", "Third"]
background: Rectangle {
color: control.enabled ? "transparent" : "red"
}
}
So as #jpnurmi suggested, the source of my problem was fixed in Qt 5.7.1.
ComboBox {
id: control
enabled: false
model: ["First", "Second", "Third"]
opacity: 1 // *
background: Rectangle {
color: control.enabled ? "transparent" : "red"
}
}
* = Adding this here, will overwrite the default opacity behaviour and then it can be controlled manually through the background component for example.

Resources