QML ProgressBar's vertical orientation does not fill to top at 100% - qml

Inside QML MainWindow, I have Slider and ProgressBar:
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
ApplicationWindow
{
visible: true
width: Screen.width/2
height: Screen.height/2
opacity: 1.00
color: "black"
RowLayout
{
anchors.fill: parent
Slider
{
id: ueSlider
Layout.fillWidth: true
Layout.fillHeight: true
Layout.margins: 8
Layout.alignment: Qt.AlignLeft|Qt.AlignVCenter
activeFocusOnPress: false
tickmarksEnabled: false
minimumValue: 0
maximumValue: 100
stepSize: 1
orientation: Qt.Vertical
onValueChanged:
{
ueProgressBar.value=value;
} // onValueChanged
} // Slider
ProgressBar
{
id: ueProgressBar
Layout.fillWidth: true
Layout.fillHeight: true
Layout.margins: 8
Layout.alignment: Qt.AlignRight|Qt.AlignVCenter
orientation: Qt.Vertical
indeterminate: false
onValueChanged:
{
print("ProgressBar value: "+value);
} // onValueChanged
Component.onCompleted:
{
minimumValue=ueSlider.minimumValue;
maximumValue=ueSlider.maximumValue;
value=ueSlider.value;
} // Component.onCompleted
} // ProgressBar
} // RowLayout
} // ApplicationWindow
Now, the ProgressBar is "connected" to Slider - when I change value of Slider, the ProgressBar's value changes. If I change ProgressBar's orientation to Qt.Horizontal, everything works fine, but if I change its orienation to Qt.Vertical, run example and push Slider to top (to its maximumValue), the ProgressBar does not go to 100%:
Why the hell?!

Related

Opacity change on button hovered glitch QML

I have created a custom virtual keyboard where the components are buttons, whose attributes I have defined in the code below . When I rapidly move the mouse across the buttons, I find that there is a 'flashing' effect whereby the button opacity appears to momentarily drop to 0 and then return. How can I prevent this flashing effect?
import QtQuick 2.15
import QtQuick.Controls 2.12
import QtGraphicalEffects 1.0
import "definitions.js" as Defs
Button {
id: keyboardButton
property bool specialButton: false
contentItem: Text {
text: keyboardButton.text
font.family: Defs.font
font.pointSize: Defs.defaultTextSize
color: Defs.ivory
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
id: background
property double op: specialButton ? 0.7 : 0.5
color: Defs.b_blue
opacity: op
radius: 0
OpacityAnimator on opacity{
running: keyboardButton.hovered
from: background.opacity
to: background.op + 0.05
duration: 100
}
OpacityAnimator on opacity{
running: !keyboardButton.hovered
from: background.op + 0.05
to: background.op
duration: 100
}
}
}
Using one animator fixes it for me:
import QtQuick 2.15
import QtQuick.Controls 2.15
ApplicationWindow {
width: 640
height: 480
visible: true
Flow {
anchors.fill: parent
Repeater {
model: 100
Button {
id: keyboardButton
property bool specialButton: false
contentItem: Text {
text: keyboardButton.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
color: "steelblue"
opacity: hovered ? baseOpacity + 0.15 : baseOpacity
radius: 0
property double baseOpacity: keyboardButton.specialButton ? 0.7 : 0.5
Behavior on opacity {
OpacityAnimator {
duration: 100
}
}
}
}
}
}
}

Flickable scrollbar malfunctioning

I have created a TextArea inside a flickable, and when I add lots of newlines the area scrolls as expected. However, although a scrollbar appears when I type more lines than the available height, if I try to drag the scrollbar it resets to fully colored (nothing to drag) and just generally misbehaves.
What is wrong with my scrollbar?
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
id: box
width: 640
height: 180
visible: true
title: qsTr("ScrollBar Mystery")
Flickable {
id: inputWrapper
anchors.fill: parent
ScrollBar.vertical: ScrollBar {
id: scrollBar
policy: ScrollBar.AlwaysOn
anchors.left: box.right
}
Keys.onUpPressed: scrollBar.decrease()
Keys.onDownPressed: scrollBar.increase()
clip: true
flickableDirection: Flickable.VerticalFlick
function ensureVisible(r)
{
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x+r.width)
contentX = r.x+r.width-width;
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
}
TextEdit {
id: input
anchors.fill: parent
text: ""
focus: true
wrapMode: TextEdit.Wrap
onCursorRectangleChanged: inputWrapper.ensureVisible(cursorRectangle)
} // TextEdit
} // Flickable
} // Window
you forget to set contentHeight and contentWidth
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
Window {
id: box
width: 640
height: 180
visible: true
title: qsTr("ScrollBar Mystery")
Flickable {
id: inputWrapper
anchors.fill: parent
contentHeight: input.implicitHeight
contentWidth: input.implicitWidth
ScrollBar.vertical: ScrollBar {
id: scrollBar
policy: ScrollBar.AlwaysOn
anchors.left: box.right
}
Keys.onUpPressed: scrollBar.decrease()
Keys.onDownPressed: scrollBar.increase()
clip: true
flickableDirection: Flickable.VerticalFlick
function ensureVisible(r)
{
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x+r.width)
contentX = r.x+r.width-width;
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
}
TextEdit {
id: input
anchors.fill: parent
text: ""
focus: true
wrapMode: TextEdit.Wrap
onCursorRectangleChanged: inputWrapper.ensureVisible(cursorRectangle)
} // TextEdit
} // Flickable
} // Window

QtQuick and KDE theming issues

I've made some QtQuick programs, and I thought it was all working fine, till I tried them out on my laptop, which is running KDE, with the Breeze Dark theme.
A simple program with a label is barely readable:
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window
{
visible: true
Label
{
font.pointSize: 20
text: "Hello world!"
}
}
With KDE Breeze Dark:
With XFCE:
I have a customised combobox too, and it looks terrible under KDE. It has the same issue on the default KDE theme, just with the colours inverted:
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import QtQuick 2.7
Window
{
visible: true
minimumWidth: 200
minimumHeight: 200
ComboBox
{
id: combo
model: ["Apple", "Banana", "Orange"]
width: 150
height: 50
delegate: ItemDelegate
{
id: item
width: parent.width
contentItem: Text
{
text: modelData
font.pointSize: 15
}
MouseArea
{
anchors.fill: parent
hoverEnabled: true
propagateComposedEvents: true
onClicked: mouse.accepted = false
onPressed: mouse.accepted = false
onReleased: mouse.accepted = false
onDoubleClicked: mouse.accepted = false
onPositionChanged: mouse.accepted = false
onPressAndHold: mouse.accepted = false
onEntered:
{
item.highlighted = true
}
onExited:
{
item.highlighted = false
}
}
}
contentItem: Text
{
id: dropDown
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pointSize: 15
text: combo.displayText
}
}
}
With KDE Breeze Dark:
With XFCE:
So, I'm not sure if this is a KDE issue, or a QtQuick issue.
I guess I want to know how I can either disable KDE theming of certain programs, or modify my Qml to display my programs nicely when themed.
I couldn't find barely any literature on QtQuick theming, aside from some proposals or ways to manually implement it.
You can use SystemPalette. For example:
Window {
visible: true
color: palette.window
Label {
font.pointSize: 20
text: "Hello world!"
}
SystemPalette {
id: palette
colorGroup: SystemPalette.Active
}
}

Image size different after second click on it

I have following minimal working example, taken from my current project:
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
Window {
visible: true
width: Screen.width/2
height: Screen.height/2
property real ueMinOpacity: 0.00
property real ueMaxOpacity: 1.00
Rectangle {
anchors.fill: parent
anchors.margins: 8
border.color: "#4682b4"
radius: 16
clip: true
gradient: Gradient {
GradientStop {
position: 0
color: "#ffffff"
} // GradientStop
GradientStop {
position: 1
color: "#303030"
} // GradientStop
} // Gradient
Rectangle {
anchors.fill: parent
antialiasing: true
border.color: "#4682b4"
border.width: 1
radius: 16
clip: true
gradient: Gradient {
GradientStop {
position: 0
color: "#ffffff"
} // GradientStop
GradientStop {
position: 1
color: "#000000"
} // GradientStop
} // Gradient
RowLayout {
spacing: 8
anchors.fill: parent
TextField {
id: ueProductSearchTextField
antialiasing: true
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignLeft|Qt.AlignVCenter
Layout.margins: 8
placeholderText: qsTr("Enter product info")
} // TextField
Rectangle {
id: ueImageWrapper
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight|Qt.AlignVCenter
Layout.margins: 8
antialiasing: true
border.color: "#4682b4"
border.width: 1
radius: 16
clip: true
visible: ueProductSearchTextField.length > 0
gradient: Gradient {
GradientStop {
position: 0
color: "#636363"
} // GradientStop
GradientStop {
position: 1
color: "#303030"
} // GradientStop
} // Gradient
Image {
anchors.fill: parent
source: "http://www.clipartbest.com/cliparts/9iR/gEX/9iRgEXXxT.png"
antialiasing: true
clip: true
smooth: true
fillMode: Image.PreserveAspectFit
horizontalAlignment: Image.AlignHCenter
verticalAlignment: Image.AlignVCenter
sourceSize.width: 96
sourceSize.height: 96
} // Image
MouseArea {
anchors.fill: parent
enabled: ueImageWrapper.visible
onClicked: {
ueProductSearchTextField.text="";
} // onClicked
} // MouseArea
onWidthChanged: {
print("ueImageWrapper.width:"+ueImageWrapper.width);
} // onWidthChanged
onHeightChanged: {
print("ueImageWrapper.height:"+ueImageWrapper.height);
} // onHeightChanged
} // Rectangle
} // RowLayout
} // Rectangle
} // Rectangle
} // Window
Now, the purpose of this Item/Rectangle is to filter database records according to TextField's entered value, which works perfectly. However, once TextField's text is not empty anymore (when user enters some string), on the right side of Layout Image for clearing text is shown via OpacityAnimator. Once the app is launched, I get following screenshot - clear text icon is hidden since there is not text in TextField:
Then, I enter some text into TextField and clear text icon pops up:
Then, for instance, I clear text by clicking on clear text icon and it (icon) is hidden again, which is ok:
And finally, I reenter text into TextField, clear text icon is visible again, but it has different size:
Why? I did not change the code. It must be some problem with Layouts, but I simply do not see it! Here is also a debug output from onWidthChanged and onHeightChanged handlers:
qml: ueImageWrapper.width:37.56521739130435
qml: ueImageWrapper.height:480
qml: ueImageWrapper.width:132.92307692307693
qml: ueImageWrapper.width:133.83783783783784
BaCaRoZzo's suggestion works, but I'm also a bit unsure about why it behaves the way it does. If you take a simpler example:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0
Window {
visible: true
width: 800
height: 800
Shortcut {
sequence: "Ctrl+Q"
onActivated: Qt.quit()
}
Item {
id: boundary
width: 400
height: 400
anchors.centerIn: parent
RowLayout {
anchors.fill: parent
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "steelblue"
}
Rectangle {
id: rect
Layout.fillWidth: true
Layout.fillHeight: true
color: "salmon"
visible: false
}
}
}
Rectangle {
anchors.fill: boundary
color: "transparent"
border.color: "black"
}
Button {
text: "Toggle visibility"
onClicked: rect.visible = !rect.visible
}
}
The second rectangle starts off being invisible, and is then shown/hidden by clicking the button. However, when it starts off as invisible, it never gets a size once shown. On the other hand, if it starts off visible, then it gets half the width of the layout.
If you read the documentation carefully, it doesn't say that it's necessary to set a preferredWidth/preferredHeight if you just want to make an item fill the available space. For that reason, it seems like a bug in how layouts handle initial visibility of their items. I'd suggest filing a bug report.

QML Row element refuses to work

I know I should be using Row, Column etc. rather than items anchored by ID to make my code simpler and easier to read. But they refuse to work most of the time. For example, in this case:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
ListView {
id: listView
anchors.fill: parent
topMargin: spacing
anchors.leftMargin: spacing
anchors.rightMargin: spacing
clip: true
spacing: 0.5 * pxPermm
model: SqlQueryModel {}
delegate: Rectangle {
id: delegateItem
color: "white"
height: 14 * pxPermm
width: listView.width
clip: true
Row {
id: row
anchors.fill: delegateItem
spacing: pxPermm
Image {
height: row.height
width: height
source: "qrc:/resources/ryba.jpg"
fillMode: Image.PreserveAspectCrop
}
Item {
id: textItem
height: row.height
Label {
anchors.left: textItem.left
anchors.top: textItem.top
text: nazov
font.bold: true
}
Label {
anchors.left: textItem.left
anchors.bottom: textItem.bottom
text: cas
}
}
}
}
}
This shows two Labels on the top of an Image in the delegate of list view. Not two labels to the right of the image, as you would expect. However, this code works:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
ListView {
id: listView
anchors.fill: parent
topMargin: spacing
anchors.leftMargin: spacing
anchors.rightMargin: spacing
clip: true
spacing: 0.5 * pxPermm
model: SqlQueryModel {}
delegate: Rectangle {
id: delegateItem
color: "white"
height: 14 * pxPermm
width: listView.width
clip: true
Row {
id: row
anchors.fill: delegateItem
spacing: pxPermm
Image {
height: row.height
width: height
source: "qrc:/resources/ryba.jpg"
fillMode: Image.PreserveAspectCrop
}
Label {
text: nazov
font.bold: true
}
}
}
}
Of course I need to show more than one label in the delegate. What am I missing here?
It turns out that Item has zero width by default. The code works properly after the width is set:
Item {
id: textItem
height: row.height
width: childrenRect.width
// labels etc
}