Force scrollbar to display left side of content and not right side of contentn - qml

I've a TextArea within a ScrollView.
In this TextArea the text appends to be larger than width of the TextArea. Hence the use of ScrollView and scrollbars.
I would like the scrollbar to display the beginning of the line by default. But it is always showing the end of the line.
How can instruct the scrollbar to stay on its left by default ?
Dialog {
id: workDialog
modality: Qt.ApplicationModal
visible: false
width: 900
height: 700
standardButtons: StandardButton.Abort
ColumnLayout {
anchors.fill: parent
spacing: 5
anchors.topMargin: 10
anchors.rightMargin: 10
anchors.leftMargin: 10
anchors.bottomMargin: 5
Label {
id: currentStatus
Layout.preferredWidth: 600
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
text: qsTr("Running...")
}
ScrollView {
id: view
Layout.fillWidth: true
Layout.fillHeight: true
Layout.maximumHeight: 700
clip: true
TextArea {
id: resultText
//anchors.fill: parent
anchors.margins: 5
selectByMouse: true
selectByKeyboard: true
cursorVisible: true
readOnly: true
focus: true
}
ScrollBar.horizontal.policy: ScrollBar.AsNeeded
ScrollBar.horizontal.position: 0
ScrollBar.vertical.policy: ScrollBar.AsNeeded
}
}
onRejected: {
abortRequested = true
}
}
I tried by setting the ScrollBar.horizontal.position: 0 but it has no effect.
Thanks

Related

QML Change ScrollBar Handle Color

I want to change the scrollbar handle color, and follow the Qt doc
https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-scrollbar
here is my code.
ScrollView {
id: view
anchors.top: parent.top
anchors.left: parent.left
contentHeight: 300
contentWidth: view.width
width: 200
height: 200
focus: true
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
Label {
text: "ABC"
font.pixelSize: 224
}
background: Rectangle{
color:"pink"
}
ScrollBar.vertical: ScrollBar {
parent: view
id: control
active: true
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: 100
radius: width / 2
color: control.pressed ? "#81e889" : "#c2f4c6"
}
}
}
enter image description here
this result the handle will fill with scrollbar.
how to changed handle color and do not fill scrollbar?
here is update.
Try to setting implicitHeight to view.contentHeight
ScrollBar.vertical: ScrollBar {
parent: view
id: control
active: true
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: view.contentHeight
radius: width / 2
color: control.pressed ? "#81e889" : "#c2f4c6"
}
}
here is result
It is have same problem,it's change the whole ScrollBar, not handle.

transferring the same images logic to another file

Is it possible to transfer the same code logic in another page, in which these two images are taken as alias or something similar and they behave in the same pattern of "if statement" logic on the other QML file(2) when this button is pressed from the first QML file(1)?
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Studio.Components 1.0
import QtQuick.Timeline 1.0
Item {
id: root
width: 500
height: 500
property alias locking: locking
Text {
id: confirmSign
text: qsTr("")
anchors.left: parent.left
anchors.top: parent.top
font.styleName: "Bold"
anchors.leftMargin: 70
anchors.topMargin: 55
color: "white"
font.pointSize: 10
font.family: "Tahoma"
}
RoundButton {
id: locking
y: 70
width: 90
height: 90
anchors.left: password_field.right
anchors.leftMargin: 15
Image {
id: unlck
anchors.centerIn: parent
source: "Images/Unlocked.png"
visible: false
}
Image {
id: lcked
anchors.centerIn: parent
source: "Images/Locked.png"
visible: true
}
onClicked: {
passBlocker.visible = true
confirmSign.text = qsTr("The ToolBar is 'Locked' ");
confirmSign.color = "#ffffff";
lcked.visible = true
unlck.visible = false
}
}
}
You can create a new file just for the lock image and use it wherever you want.
Something like this:
File LockImage.qml
Item {
property bool locked: false
Image {
id: lcked
anchors.centerIn: parent
source: locked? "Images/Locked.png": "Images/Unlocked.png"
visible: true
}
}
Side note: you don’t need to change properties using clicked handler. Prefer using the checked property of Button

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

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?!

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.

Set maximum width for RowLayout

I'm trying to build a custom control where I can place other controls (Buttons, Sliders, edit fields, etc.) grouped together.
The control should appear on the right side of the window and should have a fixed width of 200. This works fine:
RowLayout {
Item {
Layout.fillWidth: true
}
MyControl {
Layout.fillHeight: true
Layout.preferredWidth: 200
}
}
Now the problem is with the layouts and controls I used inside MyControl.
I'm using a Rectangle with a ColumnControl in it and in the ColumnControl nested the GroupBoxes (see code below).
In one of the GroupBoxes I want to place several Buttons in a row so I am using a RowLayout (I tried Row also, same result). If I only put two or three Buttons in a row the Buttons get stretched to fill the entire width and everything is fine. But when I use more Buttons, they are not shrinked below a certain size. Instead the RowLayout grows to the right and some of the Buttons are not visible since they are positioned outside the window.
It seems that the RowLayout calculates the size of it's children first and then resizes itself. Now what I want is that the RowLayout is fixed to the parent width and the children are shrinked to fit into the parent.
I managed to do that with a workaround but I'm not happy with that. There must be a more elegant way. I also tried to set the width of the RowLayout to the parent.width but got binding loops. Everything looked fine but I don't want to write code which starts with a couple of warnings.
Here's the code of the control:
Rectangle {
id: rootRect
ColumnLayout {
anchors.fill: parent
spacing: 4
GroupBox {
Layout.fillWidth: true
title: "GroupBox Title"
RowLayout {
id: buttonGroupWithWorkaround
enabled: false
anchors.fill: parent
//the workaround:
property int numberOfButtons: 6
property int buttonWidth: (rootRect.width - 2 * buttonGroupWithWorkaround.spacing) / numberOfButtons - buttonGroupWithWorkaround.spacing
Button {
Layout.preferredWidth: buttonGroupWithWorkaround.buttonWidth
text: "|<"
}
Button {
Layout.preferredWidth: buttonGroupWithWorkaround.buttonWidth
text: "<<"
}
Button {
Layout.preferredWidth: buttonGroupWithWorkaround.buttonWidth
text: "<"
}
Button {
Layout.preferredWidth: buttonGroupWithWorkaround.buttonWidth
text: ">"
}
Button {
Layout.preferredWidth: buttonGroupWithWorkaround.buttonWidth
text: ">>"
}
Button {
Layout.preferredWidth: buttonGroupWithWorkaround.buttonWidth
text: ">|"
}
}
}
GroupBox {
Layout.fillWidth: true
title: "NextGroupBox Title"
RowLayout {
id: theButtonGroup
enabled: false
anchors.fill: parent
Button {
//this doesn't work
Layout.fillWidth: true
text: "|<"
}
Button {
Layout.fillWidth: true
text: "<<"
}
Button {
Layout.fillWidth: true
text: "<"
}
Button {
Layout.fillWidth: true
text: ">"
}
Button {
Layout.fillWidth: true
text: ">>"
}
Button {
Layout.fillWidth: true
text: ">|"
}
}
}
GroupBox {
Layout.fillWidth: true
title: "OtherGroupBox Title"
//some other controls
}
}
}
Sizing can be sometimes a little bit tricky.
fillWidth ensures that the Buttons grow or shrink to fill the available space. However, this behaviour is not arbitrary. It follows other constraints set on the Item. In particular the size is never shrunk under the implicitWidth of the Item.
Hence, in this case you can solve the issue by setting a smaller implicitWidth, like this:
Button {
Layout.fillWidth: true
text: ">"
implicitWidth: 20 // the minimum width will be 20!
}
Alternatively you can define a custom ButtonStyle which defines a well-sized label but it really sounds overkilling in this specific case.
Have also a look at this answer (or other resources on SO) to have a better grasp about layouts/sizing.