ListView positionViewAtIndex() not working - qt

I have two ListViews in a QML project that are both running off of the same model. I am trying to get them to start out at different indices (the model starts with 2 ListElements in it). In order to do this, I call positionViewAtIndex when the component completes:
ListView {
model: mymodel
Component.onCompleted: positionViewAtIndex(1,ListView.Beginning)
//...
}
However, neither ListView actually is positioned at the desired index. Is there something I'm not doing? The only solution that I have seen for this problem is to ensure that you're not calling the method before the ListView completes, but I am doing that.
I am using Qt 5.2/QtQuick 2.0.
Edit: After playing around with the other positioner functions, I have found that none of them work. I have also found that changing currentIndex does not work either. Furthermore, I have found that currentIndex is not being changed with the view -- onCurrentIndexChanged is never being fired.

So, I figured it out. It turns out that a ListView instantiates its delegates before it worries about its own properties...so the delegate was only reading off of the ListView's width before the ListView set its own dimensions. When a delegate has a width/height property in the orientation of the view equal to zero, the view will not know where to scroll to when positionViewAtIndex() is called. So, in order to fix this, you have to use a conditional binding:
Component {
id: myDelegate
Item {
width: ListView.view.width == 0 ? 480 /*or some preset*/ : ListView.view.width
}
}
This will give the delegate a nonzero width and cause the positionViewAtIndex() function to work.
Of course, if your ListView is vertical, then you need to set the height property and not the width property.

Alternatively you can set currentIndex to 1

Related

Wrong filling order when loading ListView elements with Loader

I'm using a Loader in a ListView delegate to increase the performance when loading expensive delegate models.
My code looks like this:
delegate: Component {
Loader {
asynchronous: true
sourceComponent: MyDelegateComponent {}
}
}
The model comes from C++ (QAbstractListModel implementation).
The problem is that the filling order of the list is wrong. It comes from bottom to top, creating a strange view for the user, who needs to wait to see the first list element.
Is it possible to change this filling order to load top element first? The model in the C++ data is well ordered.

What is best way to load either Rectangle(drawn by code) or Image in Qml?

I have a Qml file with one 'Rectangle' and an 'Image'. I want to load either one based on the property set in my.cpp file.
Please help me to find a best way to do this.
Actually I could think two possible ways to do the same:
1) First approach is to have both the element (the image and rectangle), defined in the respective QML, and to control their visibility from my.cpp file. I can have a property, this property can control the visibility of either of the two. Drawback in this approach is that even though only one element has to be displayed, two will be created.
2) Second approach is that we can have two components and load either one using "Loader" depending on the property set from the my.cpp.
Ex:
'
Component
{
id:img
Image
{
id: myImage
source:currentdir + "/img_production/Separator/myImage.png"
width: 10
height: 79
}
}
Component
{
id:rect
Rectangle
{
id:re
height: 82
width: 10
color: "#FFFFFF"
}
}
Loader
{
id: itemDisplay
sourceComponent: style.flag? rect : img
anchors.fill: parent.fill
}
'
Looking for some expert suggestions.
PS: style.flag is property set by my.cpp to Qml.
In this case, where both items are simple base types, I would go for the visibility change.
Having both elements instantiated directly makes it easier to refer to them in bindings or bind to their properties.
It also means their allocation only happens once, reducing the chance of memory fragmentation
If you are worried about the image consuming too much memory while the rectangle is shown you could still make the image`s source property depend in the visiblity value, i.e. unload the image when not showing the Image element.

What's the simplest way to get the currently visible rows (first,last) of a QML TableView?

I need to access currently visible rows (first, last) from a JavaScript function, that is defined inside a TableView.
TableView
{
function getVisibleRows()
{
...
}
}
I see that ListView (what is a Flickable) has a contentY property which would make the problem trivial, but TableView has not. Also, TableView is implemented in terms of a ListView, so there is a ListView involved, but I am not sure how to access it.
Thank You!
I've figured out. I simply need to access flickableItem.contentY.
Use the viewport property of Scrollview (inherited by TableView), which
determines the current "window" on the contentItem. In other words, it
clips it and the size of the viewport tells you how much of the
content area is visible.
viewport return a complete qml item so you can get a lot of position data.

QML Minimum drag/flick distance for changing item

I have a ListView in QML using theese properties :
ListView {
id : list
boundsBehaviour: Flickable.StopAtBounds
snapMode: PathView.SnapOneItem
highlightFollowsCurrentItem: true
highlightRangeMode: ListView.StrictlyEnforceRange
...
}
My problem is the following :
I'm trying to determine exactly when the drag/flick will made the list move to the next/previous item or staying on the same one when releasing the touch.
Is there a property to modify or something useful to know which behaviour will happen ?
Thanks.
you are looking for startDragDistance property in QApplication class, the default value of startDragDistance is 10 pixels for Windows (it depends on OS)
In order to set drag distance to 50 pixels, you can use the following line
QApplication::setStartDragDistance(50);

QML : If condition in delegate?

I'm designing a spinner list control, which displays 3 items at a time.
Its working fine as required behaviour the only issue am facing is I need the central element appearance little bigger.
The approach which I can think as of now is to have an if condition in the delegate, which on the basis of current index increases the font size.
Is the above approach is possible? Any suggestions to achieve the particular behaviour
Below is the code snippet
SpinnerData {
id: spinner
focus: true
model: 20
delegate: Text { font.pixelSize: spinner.height/4.5; text: index; height: spinner.height }
}
I don't know the details of your component but here you can see implementation of the same control in Qt Quick Components.

Resources