In QML, the tab bar can be positioned as either TabBar.Header or TabBar.Footer, and assigning it to the footer item of ApplicationWindow automatically assigns it the latter position. This means the tab bar rests at the very bottom of the page. I, however, would like the tab bar to appear slightly above that bottom position (still at the bottom of the page, but with some space between the tab bar and the bottom edge). Is there a way to achieve this without removing the tab bar from the footer position?
Edit 1: Updated question to provide some clarity if needed.
You can customize the background of the TabButton.
You can fill color in only 90% of the TabButton. It gives an impression that your TabButton is above the bottom.
TabButton {
background: Rectangle {
height: parent.height * 0.9
color: bar.currentIndex == 0 ? "green" : "grey"
}
}
Related
I want to specify anchors for all sides using anchors.margins, but set a side anchor, like anchors.leftMargin to a different value.
For example:
Rectangle {
id: rect
width: 100; height: 100
color: "black"
Rectangle {
anchors {
fill: parent
leftMargin: 0
margins: 30
}
color: "lime"
}
}
Which shows:
It seems to work, but is this a feature or a bug waiting to happen? Isn't margins a shortcut that sets all side anchor margins and the fact that it works just due to the order in which bindings are evaluated? If someone modifies the code might anchors.margins overwrite the leftMargin property?
Anchors.margins provides the default value for the more specific margin properties. So, what you are doing is safe and supported.
It is safe to set side anchors and anchors.margins together.
anchors.margins, anchors.leftMargin, anchors.topMargin, anchors.rightMargin, and anchors.bottomMargin are all separate properties. The default value for all side anchors is anchors.margins; assigning undefined to a side anchor reverts it to the anchors.margins value.
Is there a way to style the cursorDelegate on a TextArea/TextInput so that it ends up taller and thicker than the default one?
With the following code, I can currently get one that has the following properties:
Thicker than normal, at 4px wide
Taller than the rest of the text, with bits sticking out above/below the line as wanted. BUT, this only works until the user moves the cursor. Then, the vertical size gets clipped again, and can't be reset.
TextArea {
id: editor
cursorDelegate: Rectangle {
width: 4
property int vpad: 4
y: editor.cursorRectangle.y - (vpad / 2)
height: editor.cursorRectangle.height + vpad
}
}
It looks like the y and height bindings are getting overwritten by whatever sets those automatically internally.
Trying to overwrite these again myself using a onCursorPositionChanged handler on the TextArea fails, as you cannot write to cursorDelegate.
Managed to find a solution. Instead of setting these values in the normal way, you need to set these on the change handlers for those properties.
TextArea {
id: editor
cursorDelegate: Rectangle {
width: 4
property int vpad: 4
onYChanged: editor.cursorRectangle.y - (vpad / 2)
onHeightChanged: editor.cursorRectangle.height + vpad
}
}
This seems to resist the widgets auto behaviour that was overwriting our values.
For a project I am showing data in a table, the newest data is the most relevant so I want that to be the most visible but it should also be possible to see the earlier data.
The following code contains the view with a scrollbar.
ScrollView{
id:dataScrollView
width: parent.width
anchors.top: headerWrapper.bottom
height:parent.height - headerWrapper.height
ScrollBar.vertical.policy: ScrollBar.AlwaysOn;
clip: true
TableView{
id: table
columnSpacing: 1
rowSpacing: 1
clip: true
implicitHeight: column.height - 33
implicitWidth: column.width
model: modelItem
delegate: compColored
onContentHeightChanged: {
//new data has come in I want to scroll to the bottom
console.log("update scroll to bottom" )
}
}
}
I know exactly where to put the code but i do not know how I can make the scrollbar go to the bottom or how to set the position of the scrollbar.
Can someone point me out to how I can set the position of the scrollbar?
As TableView inherits Flickable, you can reposition the contentItem within the viewport simply by:
onContentHeightChanged: {
table.contentY = table.contentHeight - table.height
}
and the Flickable's contentItem bottom area will be visible in the viewport.
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 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"
}
}
}
}