Is there a way to have subheader on a TableView in qml? - qt

I'm trying to adapt a TableView that has TableViewColumns in a way that it has header and subheaders.
For example:
table with subheaders
As far as i know i can only do it like this:
the table i have now
In code i frequently do:
TableViewColumn {
id: zoneNumber
title: qsTr("teste")
horizontalAlignment: Text.AlignHCenter
width: col_zone_width
movable: false
resizable: false
delegate:
Rectangle {
border.width: 1
border.color: globals.table.borderColor
color: globals.table.color
height: parent.height
anchors.fill: parent
Text {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: globals.text.textColor
text: (styleData.row + 1)
font.bold: globals.menu.fontBold
font.pointSize: globals.text.textSize
font.family: robotoRegular.name
}
}
}
Reading the documentation title in TableViewColumn only accepts a string.
Then on TableView i have,
headerDelegate: Rectangle{
id:recHeader
width:styleData.width+20
height:301
Text {
anchors.fill:parent
text:styleData.value
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
That way it seems impossible to do what i'm trying to achieve.
Is there a solution for this? maybe parsing styleData.value to return a different component?
note: i'm using TableViewColumn from QtQuick.Controls 1.4, TableView from QtQuick 2.2

Related

Customizing Buttons in QML

I am new to QML development. I would like to customize the QML button for our requirement. In some QML sample projects, the customization is done as Button.QML by
drawing a rectangle and implementing mouse area onclick() events. example,
import QtQuick 2.5
Rectangle {
id: button
signal clicked
property alias text: text.text
border.width: 1
border.color: "white"
property real textHeight: height - 2
property real fontHeight: 0.3
property bool pressed: mouse.pressed
property real implicitMargin: (width - text.implicitWidth) / 2
Text {
id: text
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: parent.textHeight
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: height * fontHeight
color: "#1b1c1d"
font.family: "Open Sans Regular"
}
MouseArea {
id: mouse
anchors.fill: parent
onClicked: button.clicked()
}
}
This code is works for me. But I saw another QT example as
import QtQuick 2.12
import QtQuick.Controls 2.0
Button {
id: controlBt
text: qsTr("Test")
font.pixelSize: 32
contentItem: Text {
text: controlBt.text
font: controlBt.font
opacity: enabled ? 1.0 : 0.3
color: controlBt.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 550
implicitHeight: 66
opacity: enabled ? 1 : 0.3
border.color: controlBt.down ? "#17a81a" : "#21be2b"
border.width: 1
radius: 2
}
}
But by using this code for customization, Focus and key events are not working for the button.
Could anyone provide me the best and correct way to customize a QML button.
Thanks
I have used the following code for the customization
UiButton.qml
import QtQuick 2.12
import QtQuick.Controls 2.0
Button {
id: controlBt
text: qsTr("Test")
font.pixelSize: 32
contentItem: Text {
text: controlBt.text
font: controlBt.font
opacity: enabled ? 1.0 : 0.3
color: controlBt.down ? "#17a81a" : "#21be2b"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
background: Rectangle {
implicitWidth: 550
implicitHeight: 66
opacity: enabled ? 1 : 0.3
border.color: controlBt.down ? "#17a81a" : "#21be2b"
border.width: 1
radius: 2
}
}
In the test.qml i have used the above button as
UiButton
{
id: idTestButton
x: 250
y: 512
focus: true
visible: false
KeyNavigation.down:
{
console.log(">>>>>>>>>>>>>>>>>>>>idTestButton: down")
}
Keys.onLeftPressed:
{
console.log(">>>>>>>>>>>>>>>>>>>>idTestButton: onLeftPressed")
}
onClicked: {
console.log(">>>>>>>>>>>>>>>>>>>>idTestButton: onClicked")
}
}
in the application, I have a listView and on pressing down from the last item of listView, i need to set focus on the test button.
on listView Keys.onDownPressed:
Keys.onDownPressed:
{
// on pressing down from last item, I set focus to button as
idTestButton.forceActiveFocus()
}
on using forceActiveFocus(), everything worked for me. Thank you all for your support
Thanks you

QtQuick: Resize two textfields with Elide on both

I've got two Labels A and B in a row which need to be anchored together such that there is no spacing between them. A is not allowed to be larger than it's content, because B is like a detail label. It would be weird to see Google Chrome_____(the current browser). You'll want Google Chrome (the current browser)____ in this case.
Both have a common parent that they can fill up. Content-wise both A and B can be the larger of the two. The whole thing should be left aligned such that A is anchored to the parent's left and B.left == A.right.
When there is not enough space, both items should shrink and elide until they fit the parent, eg Google Chr..(The current br...
This last part is what I could not figure out how to do.
I'm using 2 labels instead of 1 because they need their own elision and their own styling.
My current solution will simply elide B, not shrink A at all.
RowLayout
{
spacing: 0
anchors.left: parent.left
anchors.right: customisedSettings.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
Label
{
id: textLabelA
text: qualityName()
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
Layout.margins: 0
height: contentHeight
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
elide: Text.ElideRight
function qualityName() {
[...]
}
}
Label
{
id: textLabelDetail
text: activeQualityDetailText()
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text_detail")
anchors.verticalCenter: textLabelA.verticalCenter
Layout.margins: 0
Layout.fillWidth: true
height: contentHeight
verticalAlignment: Text.AlignVCenter
renderType: Text.NativeRendering
elide: Text.ElideRight
function activeQualityDetailText()
{
[..]
}
}
}
You can do that by putting them in a RowLayout and setting Layout.fillWidth: true on both of them so they both shrink.
To ensure that the first Label isn't larger than needed, set Layout.maximumWidth: implicitWidth.
This gives us :
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Window 2.3
import QtQuick.Layouts 1.2
Window {
visible: true
width: 600
height: 400
RowLayout {
anchors.fill: parent
Label {
text: "Google Chrome"
Layout.fillWidth: true
Layout.maximumWidth: implicitWidth
elide: Text.ElideRight
}
Label {
text: "(the current browser)"
color: "darkgray"
Layout.fillWidth: true
elide: Text.ElideRight
}
}
}

QML Display multi text in one ROW

I have problem in displaying the text inside a listview in aligned manner.
MyCodes are
delegate: Rectangle{
width : parent.width
height: textId.implicitHeight+20
color: "white"
border.color: "#e4e4e4"
radius: 0
RowLayout{
anchors.fill: parent
anchors.margins: 20
Text{
id:textId
text : names
// wrapMode: Text.Wrap
// Layout.fillWidth: true
// width:300
}
Text{
id:textId2
text :favoriteColor
// wrapMode: Text.Wrap
//Layout.fillWidth: true
//width: parent.width
// width:300
}
Text{
id:textId1
text :age
// wrapMode: Text.Wrap
// width: parent.width
}
}
Output is
I am expecting the textfields i.e. names, favoriteColor and age to come in more aligned manner. In Simple words showing in simple table form.
i.e. All Favoritecolors and age to start from same point throughout the list.
Thank You
You should fix width of textId2 and textId1 using Layout.preferredWidth and Layout.maximumWidth, and assign true to Layout.fillWidth for textId.
RowLayout{
anchors.fill: parent
anchors.left: parent.left
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
layoutDirection: Qt.LeftToRight
spacing: 10
Text {
id:textId
text :favoriteColor
Layout.maximumWidth: advance.width
Layout.preferredWidth: advance.width
}
Text {
id:textId1
text :age
Layout.fillWidth: true
}
}

How can I have the first element of a listview always visible when I scroll the listview?

in my code i have a ListView of 16 elements, i want that when i scroll the listview the first element must be always visible. How i can do it ?
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
ListView {
id:listview
anchors.fill: parent
model: 16
verticalLayoutDirection: ListView.BottomToTop
delegate: Rectangle {
height: listview.height/5
width: listview.width
color: Qt.rgba(Math.random(),Math.random(),Math.random(),1)
Text {
text: index
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "white"
font.pixelSize: 35
}
}
}
}
you could make use of a header. Your code will then look something like this:
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
ListView {
id:listview
anchors.fill: parent
model: 15
verticalLayoutDirection: ListView.BottomToTop
headerPositioning: ListView.OverlayHeader
header: Rectangle {
height: listview.height/5
width: listview.width
color: Qt.rgba(Math.random(),Math.random(),Math.random(),1)
z:2
Text {
text: "0"
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "white"
font.pixelSize: 35
}
}
delegate: Rectangle {
height: listview.height/5
width: listview.width
color: Qt.rgba(Math.random(),Math.random(),Math.random(),1)
Text {
text: index+1
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "white"
font.pixelSize: 35
}
}
}
}

ReferenceError: down is not defined in SpinBox QML

I am referring to https://doc.qt.io/qt-5/qtquickcontrols2-customize.html#customizing-spinbox and copy pasted the same code, But i am getting following errors:
ReferenceError: down is not defined and
ReferenceError: up is not defined.
Code:
import QtQuick 2.6
import QtQuick.Controls 2.1
SpinBox {
id: control
value: 50
editable: true
contentItem: TextInput {
z: 2
text: control.textFromValue(control.value, control.locale)
font: control.font
color: "#21be2b"
selectionColor: "#21be2b"
selectedTextColor: "#ffffff"
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
readOnly: !control.editable
validator: control.validator
inputMethodHints: Qt.ImhFormattedNumbersOnly
}
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: up.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "+"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
down.indicator: Rectangle {
x: control.mirrored ? parent.width - width : 0
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: down.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "-"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
background: Rectangle {
implicitWidth: 140
border.color: "#bdbebf"
}
}
Should i include any additional imports ?
No, you don't need to include any additional imports. It is just, that the example uses bad practice and here you see why:
This is the (reduced to modifying only the up.indicator) code of the example:
import QtQuick 2.6
import QtQuick.Controls 2.0
SpinBox {
id: control
value: 50
editable: true
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: up.pressed ? "#e4e4e4" : "#f6f6f6" // <---*
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "+"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
Here we have the SpinBox as the root element of the file.
Now lets talk about name resolution.
The line in question is marked with a // <---*
control: up.pressed ? "..." : "..."
Where does up come from? At first it will look in the object, where it is used - the Rectangle. The Rectangle has no up-property, so it will continue and looking in the root node of the file, which is the SpinBox - this has a up-property, which also has a value for pressed.
The situation looks different, when we try to use it (the wrong way). Let's add a ApplicationWindow:
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
width: 800
height: 600
visible: true
SpinBox {
id: control
value: 50
editable: true
up.indicator: Rectangle {
x: control.mirrored ? 0 : parent.width - width
height: parent.height
implicitWidth: 40
implicitHeight: 40
color: up.pressed ? "#e4e4e4" : "#f6f6f6"
border.color: enabled ? "#21be2b" : "#bdbebf"
Text {
text: "+"
font.pixelSize: control.font.pixelSize * 2
color: "#21be2b"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
}
}
Same line - will try to look up up in the Rectangle, fails and continues to the files root node, which is now an ApplicationWindow. Here it fails again. As the ApplicationWindow is not used in another file, where another files root node might exist, the search will end and finally fail.
What went wrong? The writer of the example missed the to apply the good practice to always use fully qualified identifiers: id.property.... as he did for example to define the x-value of the Rectangle.
Changing the line:
color: up.pressed ? [...]
to:
color: control.up.pressed ? [...]
will solve the problem, as we now explicitly declare where to look for the property up.
Important Lesson
Names are not resolved by going from child to parent, but always from child to the files root node and so on, until it can't go on
Always identify the object either explicitly by parent (but be aware, that you might not know what exactly the parent is. So ideally only for anchors and position) or by the objects's id

Resources