How to set background of gridview from QML file.
Nest the grid view in a Rectangle and make the delegates of the GridView elements transparent:
Rectangle {
color: "red"
GridView {
delegate: Rectangle {
color: "transparent"
}
}
}
In QML you can compose complex objects by including/nesting widgets/elements within each other.
So for including an image inside a Widget, in your case the GridView, just nest an Image element, inside GridView Element or it's sub elements as required.
GridView {
width: 800
height: 600
Image: {
source: "some-image.png"
}
}
The documentation for GridView has similar and better examples - http://doc.qt.digia.com/4.7-snapshot/qml-gridview.html#example-usage
Also look out for the anchors attribute, which will help you position the image in the parent Element, or otherwise.
Documentation for Image element is available here: http://doc.qt.digia.com/latest/qml-image.html
Related
I want to display a large amount of content, for example, a grid of multiple images inside a window that is smaller than the content, similar to a geographical map but instead of a map, I want my own components as the "map". For this minimal working example, let's take for the content a grid of images with a total size of 1000x1000 with a window into this content of only 300x300.
I have tried 2 different approaches, but I will only go into detail of the first approach as that is the one that got me closest to my desired result:
I have tried the Flickable component but the content cannot be moved outside the predefined bounds, making the user unable to move the view in order to display all the parts of the content. So the simplest solution that I'm thinking about now is if I could remove these bounds from the Flickable component, but how?
I have also tried the Map component but it requires a "plugin" and I was unable to figure out how to use this component with my own content of an image grid.
The content that I want to show is something this
Grid {
columns: 5
spacing: 2
Repeater {
model: ListModel {
ListElement {
path: 'test1'
}
ListElement {
path: 'test2'
}
// ...
ListElement {
path: 'test25'
}
}
Rectangle {
width: 200
height: 200
Image {
anchors.fill: parent
source: 'file:' + path
}
}
}
}
I tried, putting this inside the Flickable like this
Flickable {
anchors.centerIn: parent
width: 300
height: 300
contentWidth: 1000
contentHeight: 1000
clip: true
// INSERT CUSTOM GRID COMPONENT HERE
}
This results in a 300x300 view inside the content as expected, but once you start to flick through the content to view different parts of it, you are stopped by the bounds preventing you from seeing anything outside these bounds. You can see it while dragging but once you release the view of the content is reset to these bounds.
So how do I remove these bounds? (Or is there a different component more suitable for my application?)
Here is a gif that shows how the content can be dragged passed the bounds, but once released it will only go up to the bounds and not further
I found the issue, I set the contentWidth and contentHeight of the Flickable incorrectly, this example works fine. The contentWidth and contentHeight determine the bounds in which you can flick.
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)
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.
I want to create a breadcrumb in QML.
So to have a dynamic C++ model, displayed as an horizontal list of items. Each item has a fixed size to only display its content (basically a string).
I need to display all items (with the maximum of almost my window width), on top of my main background (a working area), so transparent except for the items.
What is the best container to use for that case ? Considering I do not need to scroll.
Row, RowLayout, ListView ?
Here is a code for my comment above. Flow could be replaced with Row if needed.
Flow {
spacing: 3
width: parent.width
Repeater {
model: ["root", "item1","subitem1","one more items","subitem2","item3"]
delegate: Label {
padding: 10
text: modelData
background: Rectangle {
color: "#DEDEDE"
}
}
}
}
I want to set the activeFocus for a FocusScope by clicking anywhere within an Item.
Is there a way to achieve this without having a MouseArea over the entire Item? Because it would have to overlay all elements within the Item, making them unclickable.
I'm pretty new to QtQuick/QML and have troubles understanding how to properly implement FocusScopes. I've read about propagating click signals, but couldn't get it to work.
Assuming I have something like this (no FocusScopes for readability):
Rectangle
{
id: outerRectangle
width: 1000
height: 1000
// various controls in here
Rectangle
{
id: innerRectangle
anchors.centerIn: parent
width: 200
height: 200
// even more controls in here
}
}
I want the outerRectangle to get the activeFocus when I click anywhere on the outerRectangle and vice-versa for the innerRectangle. But all controls on both Rectangles still have to work properly.
How can I achieve this?
Surround your Item with FocusScope:
FocusScope {
Item {
focus: true
}
}
See Qt Doc