Right to left Flickable - qt

when i add a child into Flickable it anchors that to the left of whole control,but i want flickable's child anchors to the right of whole control (i think when there is anything inside flickable its flickableItem implicitWidth affects the whole controls width thats why i cant use anchors.right = parent.right ), there is no layoutDirection property in Flickable and LayoutMirroring is not working in flickable, how can i force Flickable to paint child from right margin of its body?
this is my flickable control :
// ScrollableItem.qml
Flickable{
id:root
contentWidth: pane.implicitWidth
contentHeight: pane.implicitHeight
boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.AutoFlickIfNeeded
default property alias content : pane.contentItem
Pane{
id:pane
}
ScrollIndicator.vertical: ScrollIndicator{
}
ScrollIndicator.horizontal: ScrollIndicator{
}
}
and i use it like this :
ScrollableItem{
width : parent.width
height : parent.height
RowLayout{
spacing: 500
layoutDirection: Qt.RightToLeft
Button{
}
Button{
}
Button{
}
}
}
Qml dont care about width : parent.width of ScrollableItem and if i set width inside control it wont flick , i tried to use anchors.right in child's too but didnt work. is there anyway to force flickable child to flow from right of screen?
UPDATE : let me show you in a picture
you see where pane anchored? anchoring pane to right is impossible and there is no layout direction and width of pane is depend on child width which is a rowLayout so if pane width is lower than flickable width it will always drawn on the left edge of flickable which i want to drawn in right edge of flickable

Actually, a Flickable should not logically have anchoring capabilities.
So you need to explicitly move the Flickable to the right by :
// ScrollableItem.qml
Flickable{
id:root
contentWidth: pane.implicitWidth
contentHeight: pane.implicitHeight
boundsBehavior: Flickable.StopAtBounds
flickableDirection: Flickable.AutoFlickIfNeeded
default property alias content : pane.contentItem
leftMargin: pane.contentWidth >= root.width ? 0 : root.width - pane.contentWidth
contentX: pane.mirrored ? pane.width : 0;
property var lastWidth : 0
Pane{
id:pane
}
onWidthChanged: {
contentX += lastWidth-width
lastWidth = width;
}
ScrollIndicator.vertical: ScrollIndicator{}
ScrollIndicator.horizontal: ScrollIndicator{}
}
and i use it like this :
ScrollableItem{
width : parent.width
height : parent.height
LayoutMirroring.enabled: true
LayoutMirroring.childrenInherit: true
RowLayout{
spacing: 500
layoutDirection: Qt.RightToLeft
Button{
}
Button{
}
Button{
}
}
}
This works quite well for me. When the pane has smaller width than the Flickable, you should add the remaining space to leftMargin to keep the content at the right side.

Related

Set height of popup to contain contents

I want to set the size (mainly height) of my popup to fit the contents depending on how much text is shown or whether there's an icon image shown on popup. How do I set the height of popup.
Eg.
Popup {
id: popup
width: window.width/2
height: window.height/4
x: window.width/2 - width/2
y: window.height/2 - height/2
Rectangle {
id: popupContent
width: parent.width
height: parent.height
visible: notification
anchors.fill: parent
Rectangle {
id: iconField
anchors.top: parent.top
width: parent.width
height: parent.height/2
Image {
id: img
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
width: window.width/18
height: window.width/18
fillMode: Image.PreserveAspectFit
source: "qrc:/images/icons/info.png"
}
}
Rectangle {
id: textField
anchors.top: iconField.bottom
width: parent.width
height: parent.height/2
Text {
id: text1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: Text.WordWrap
text: "This long text overflows out of the popup up rectangle!"
}
}
}
}
If I use a long text then the text overflows from the popup rectangle. I tried using implicitHeight in different places but I don't understand how to apply it in this situation.
There's several issues with your code. It's hard to make a perfect answer because I don't know exactly what's intended. For example, your text will always be off the bottom of the Rectangle because you anchored textField's anchor.top to iconField.bottom, and iconField is the same size as the entire popup. But here's some ideas on how to improve it.
Your popupContent is a Rectangle, but I'm not sure if you actually are intending to draw a rectangle there or not. I think you could replace that with a ColumnLayout like the example here.
You can also manually specify the height of your content using the contentHeight property. You could set it to the height of your iconField plus the height of your textField, plus any padding you want.
Every Item has a property called childrenRect.height which will tell you the combined height of all of its children.
For all of these options though, you will need to stop setting every object's height to be the same as its parent's height.

QML TreeView - Change position of expand icon

I'm currently trying to change the layout of a QML TreeView so that the expand icon (the arrow or triangle you have to click in order to show or hide the children elements).
I tried anchoring the icon to the right of the TreeView, but for some reason it's not working, it remains on the left despite everything. Do you have any hint?
Thanks a lot!
TreeView {
id: treeView
anchors.fill: parent
model: treeModResult
style: TreeViewStyle {
branchDelegate: Rectangle {
width: 15; height: 15
color: "#00000000"
anchors.right: treeView.right
Image {
id: expandArrow
source: styleData.isExpanded ? "qrc:/img/icn_arrow_top.svg" : "qrc:/img/icn_arrow_bottom.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
}
ColorOverlay {
anchors.fill: expandArrow
source: expandArrow
color: "#293147"
}
}
}
}
Update
This is what I currently have:
This is what I would like to have:
I had the same issue, I came up with the following solution, as anchoring wasn't working for me neither..
style: TreeViewStyle {
branchDelegate: Rectangle{
id: expandIcon
x: control.width - width
control.width represents the width of the treeview.

Wrong width and position of non-attached horizontal QML ScrollBar (and ScrollIndicator) when I resize parent element from RTL

The problem is in position and width of the horizontal scrollbar and position of the content that has been scrolled when I resize the width of the window (parent) element in RTL direction.
When I do these steps:
Resize the width of window in LTR direction.
Everything is working fine.
Change scrollbar position to any other position that is different from 0.0, (for example move it all the way to the right side)
Resize the width of window in opposite (RTL) direction
Scrollbar starts to behave odd and scrollable content is in the wrong position
I get this situation:
Width of scrollbar's contentItem (aka scrollbar's handle) is wrongly calculated.
Scrollbar's position is also wrongly calculated
The content is not scrolled to the right place (property "x" of scrollable content is wrongly calculated )
What I want is that:
the width of scrollbar's contentItem (aka scrollbar's handle) increases proportionately as the width of the window increases
the content (which was in the position that its right side was completely visible) should stay in that position. And with the expansion of the window, on the left side, the other part of the content that was not visible until then, should start to show up.
The same things are happening if I try to use non-attached QML ScrollIndicator.
This seams to be the bug in QML, and I have reported it, but I need the solution now... If anyone could help, it would be great. Thanks!
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.3
Window
{
id: main
width: 400
height: 200
Rectangle
{
id: frame
clip: true
anchors.fill: parent
color: "purple"
Text
{
id: content
text: "ABCDE"
font.pixelSize: 160
x: -hbar.position * width
}
ScrollBar
{
id: hbar
hoverEnabled: true
active: true
policy: ScrollBar.AlwaysOn
visible: size < 1
orientation: Qt.Horizontal
size: frame.width / content.width
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
background: Rectangle
{
color: "black"
}
}
}
}
scrollbar behavior
You should consider using a Flickable instead of setting the position of your text manually:
Flickable {
anchors.fill: parent
contentWidth: content.paintedWidth
boundsBehavior: Flickable.StopAtBounds
ScrollBar.horizontal: ScrollBar {
hoverEnabled: true
active: true
policy: ScrollBar.AlwaysOn
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
background: Rectangle {
color: "black"
}
}
Rectangle {
id: frame
clip: true
anchors.fill: parent
color: "purple"
Text {
id: content
text: "ABCDE"
font.pixelSize: 160
}
}
}
Edit:
If you really need the ScrollBar to be attached to a Rectangle, you can add bounds to your Text position:
x: Math.min(0, Math.max(-hbar.position * width, frame.width - content.width))
with
ScrollBar {
visible: frame.width < content.width
// ...
}

QML Layout not limiting width of children

I have a QML ColumnLayout with a few children, and I want to limit its width, like so:
ColumnLayout {
width: 360
height: 480
ColumnLayout {
id: inner
Layout.maximumWidth: 200
Layout.fillHeight: true
Text {
text: "Welcome"
font.pixelSize: 18
}
Text {
text: "Long explanation that should wrap, but ends up overflowing layout"
wrapMode: Text.WrapAnywhere
}
}
Rectangle {
anchors.fill: inner
z: -1
border.color: "orange"
}
}
I get the result shown in the picture below.
The orange box shows the dimensions of the inner layout item, which is all right. However, the children text of the layout is not wrapped.
I can only fix that by adding
Layout.maximumWidth: parent.width
to my 'Text' items, but that's quite awkward approach. Am I doing anything wrong, or is this a Qt bug, or is it a design approach for some reason? I am using Qt 5.4.1.
The text will only wrap if an explicit width has been set
Docs
Text
{
width: parent.width
}

What is the difference between Row and RowLayout?

This works as intended with Row, but not with RowLayout. Why? What is the difference between the two?
ApplicationWindow {
title: "Testing"
width: 640
height: 480
//RowLayout {
Row {
anchors.fill: parent
Rectangle {
id: rect1
width: parent.width * 0.3
height: parent.height
color: "blue"
}
Rectangle {
height: parent.height
width: parent.width * 0.7
color: "red"
}
}
}
Row is a Item Positioner. Positioner items are container items that manage the positions of items in a declarative user interface.
RowLayout is part of Qt Quick Layouts. They manage both the positions and the sizes of items on a declarative user interface, and are well suited for resizable user interfaces.
Your code with RowLayout should look like this:
RowLayout{
anchors.fill: parent
spacing: 0
Rectangle{
Layout.fillHeight: true
Layout.preferredWidth: parent.width * 0.3
color: "blue"
}
Rectangle{
Layout.fillHeight: true
Layout.fillWidth: true
color: "red"
}
}
I think
Row is a container which grows the size based on the children of Row, making them line up as a row, so the children of it shall have size.
RowLayout is the wrapper of its children, giving them the ability of row positioning and resizing based on the size of RowLayout, so RowLayout shall have its own size to help the children to position and resize.

Resources