QML Display multi text in one ROW - qt

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
}
}

Related

QML ScrollBar combined with ListView

I'm new to QML and QT so don't blame me if this question is going to sound stupid for most of you but I've search all over the internet without any luck in founding an answer.
What I'm trying to do:
I'm having a ScrollView which has inside of it a ScrollBar and a ListView.
I want that at the moment when I'm scrolling the ListView elements to also move the bar from ScrollBar. In other words, I want to use the ScrollBar as an overall view of your current position, you are not supposed to touch that, its only purpose is for viewing.
My Code:
ScrollView{
implicitHeight: 100
implicitWidth: 50
anchors.fill: parent
ScrollBar.horizontal: ScrollBar{
id: hbar
active: true
policy: ScrollBar.AlwaysOn
anchors {
left: parent.left
top: parent.top
right: parent.right
}
background: Rectangle {
implicitWidth: 100
implicitHeight: 50
opacity: enabled ? 1 : 0.3
color: hbar.down ? "#red" : "black"
}
contentItem: Rectangle {
implicitWidth: 6
implicitHeight: 100
radius: width / 2
color: hbar.pressed ? "#81e889" : "#c2f4c6"
}
}
ListView {
id: listViewParent
height: listViewID.height/10*6
contentHeight: height*2
contentWidth: width*2
clip: false
interactive: false
keyNavigationWraps: true
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0
enabled: true
scale: 1
transformOrigin: Item.Center
anchors.verticalCenter: parent.verticalCenter
boundsBehavior: Flickable.DragAndOvershootBounds
flickableDirection: Flickable.HorizontalFlick
highlightMoveDuration: 0
cacheBuffer: 300
snapMode: ListView.SnapToItem
layoutDirection: Qt.LeftToRight
orientation: ListView.Vertical
model: 1
delegate:
ListView {
width: parent.width;
height: parent.height;
spacing: listViewID.width/8/9
model: MovieListModel {}
orientation: ListView.Horizontal
id: listid
delegate:
Rectangle {
property int recDynamicHeight: listViewID.height/10*6
property int recOriginalHeight: listViewID.height/10*6
property int recDynamiclWidth: listViewID.width/7
property int recOriginalWidth: listViewID.width/7
id: rectPer
width: recDynamiclWidth
height: recDynamicHeight
Image {
id: image1
anchors.fill: parent;
source: model.imgUrl
}
Text {
property bool isVisible: false
color: "#ffffff"
anchors.fill: parent
visible: textid.isVisible
id: textid
text: model.title
font.bold: true
horizontalAlignment: Text.AlignLeft
font.pixelSize: listViewID.width/8/9
topPadding: listViewID.width/8/9
leftPadding: listViewID.width/8/9
}
Text {
anchors.topMargin: listViewID.width/8/9
color: "#ffffff"
anchors.fill: parent
visible: textid.isVisible
id: yearId
text: model.year
horizontalAlignment: Text.AlignLeft
font.pixelSize: listViewID.width/8/9
topPadding: listViewID.width/8/9*2
leftPadding: listViewID.width/8/9
}
MouseArea {
anchors.fill: parent
onPressed: {
rectPer.recDynamicHeight = rectPer.recOriginalHeight;
rectPer.recDynamicHeight += rectPer.recOriginalHeight/10;
rectPer.recDynamiclWidth += rectPer.recOriginalWidth/10;
console.log(textid.isVisible);
textid.isVisible = true;
textid.visible = textid.isVisible;
console.log(sideButtonID.x);
console.log(sideButtonID.y);
console.log(model.year + " clicked");
}
onClicked: {
console.log("INDEX: " + model.id)
load_page(PageType.movie_detailed_view, model.title, model.description, model.imgUrl, model.type, model.year)
}
onReleased: {
rectPer.recDynamicHeight = rectPer.recOriginalHeight;
rectPer.recDynamiclWidth = rectPer.recOriginalWidth;
textid.isVisible = false;
textid.visible = textid.isVisible;
}
}
}
}
}
}
Layout:
You could try use a Flickable instead of a ScrollView and spawn a ListView there(delegates: Rectangles). Then, spawn the Scrollbar inside the ListView

Best way to add space around a ColumnLayout?

I like that there is a spacing property to add space between items in a layout. But is it also possible to add space around a layout?
See my code below. I try to use anchors.margins on the ColumnLayout but that does not work.
Rectangle {
id: leftSelectionRect
anchors.top: parent.top
anchors.right: leftLine.left
implicitWidth: leftSelectionLayout.implicitWidth
implicitHeight: leftSelectionLayout.implicitHeight
color: CustomProperties.Colors.transparentSelectionBackground
ColumnLayout {
id: leftSelectionLayout
spacing: CustomProperties.Margins.small
anchors.margins: CustomProperties.Margins.small // This is what I would like to do, but it does not work.
CustomComponents.HeaderText {
id: leftText
text: Converter.formatDuration(ui.selectionModel.startUs, Converter.MicroSeconds, Converter.MicroSeconds)
}
CustomComponents.HeaderText {
id: leftdeltaText
text: "Δ " + Converter.formatDuration(ui.selectionModel.deltaUs, Converter.MicroSeconds, Converter.MicroSeconds)
}
}
}
EDIT
The following is the first attempt I have made that works, but it is messy. There must be a better way:
Rectangle {
id: leftSelectionRect
anchors.top: parent.top
anchors.right: leftLine.left
implicitWidth: leftSelectionLayout.implicitWidth + CustomProperties.Margins.medium * 2
implicitHeight: leftSelectionLayout.implicitHeight + CustomProperties.Margins.small * 2
color: CustomProperties.Colors.transparentSelectionBackground
ColumnLayout {
id: leftSelectionLayout
spacing: CustomProperties.Margins.small
anchors.topMargin: CustomProperties.Margins.small
anchors.bottomMargin: CustomProperties.Margins.small
anchors.leftMargin: CustomProperties.Margins.medium
anchors.rightMargin: CustomProperties.Margins.medium
anchors.fill: parent
CustomComponents.HeaderText {
id: leftText
text: Converter.formatDuration(ui.selectionModel.startUs, Converter.MicroSeconds, Converter.MicroSeconds)
}
CustomComponents.HeaderText {
id: leftdeltaText
text: "Δ " + Converter.formatDuration(ui.selectionModel.deltaUs, Converter.MicroSeconds, Converter.MicroSeconds)
}
}
}
Do not add anchors.fill:parent to your inner ColumnLayout but to your outer wrapper component:
Item {
anchors.fill: parent
anchors.margins: 10
ColumnLayout {
id: layout
width: parent.width
spacing: 10
Rectangle {
color: "red"
Layout.preferredHeight: 100
Layout.preferredWidth: parent.width
}
Rectangle {
color: "blue"
Layout.preferredHeight: 100
Layout.preferredWidth: parent.width
}
Rectangle {
color: "green"
Layout.preferredHeight: 100
Layout.preferredWidth: parent.width
}
}
}
At all you should avoid setting height property or anchors.top AND anchors.bottom properties to your ColumnLayout because it calculates its height at its own.

ListView item covered by header after scrolling

I am trying to use a ListView with a simple header that stays on top of the list. It is working fine for most situations. When I scroll all the way to the top manually the top item is located below the header:
When I set the current index from outside the list to highlight an item the list scrolls to the highlighted item. This is expected and desired behavior. However the list scrolls in a way, that the highlighted item will be on the same height (y) as the header. Therefore the header partially covers the item. In the picture the header is transparent, the highlight is light green:
How can I set up the list so that the list content always starts below the header? Or as a workaround, how can I set the height of the current item after the automatic scroll on selection?
For completeness here is the current code of my list.
ListView {
id: particleList
anchors.fill: parent
model: particleModel
clip: true
highlight: Rectangle { color: Material.color(Material.Green); opacity: 0.2}
highlightMoveDuration: Style.animationDurationMedium
headerPositioning: ListView.OverlayHeader
header: Item {
height: 40
anchors.left: parent.left
anchors.right: parent.right
Row {
anchors.fill: parent
MediumText {
horizontalAlignment: Text.AlignHCenter
width: parent.width / 3
text: qsTr("Width")
}
MediumText {
horizontalAlignment: Text.AlignHCenter
width: parent.width / 3
text: qsTr("Height")
}
MediumText {
horizontalAlignment: Text.AlignHCenter
width: parent.width / 3
text: qsTr("Area")
}
}
}
footer: SmallText {
anchors.left: parent.left
anchors.right: parent.right
text: particleModel.count
}
populate: Transition {
NumberAnimation { properties: "x,y"; duration: 1000 }
}
delegate: Item {
height: 40
anchors.left: parent.left
anchors.right: parent.right
Row {
anchors.fill: parent
MediumText {
anchors.verticalCenter: parent.verticalCenter
width: parent.width / 3
text: model.width
horizontalAlignment: Text.AlignRight
rightPadding: 20
}
MediumText {
anchors.verticalCenter: parent.verticalCenter
width: parent.width / 3
text: model.height
horizontalAlignment: Text.AlignRight
rightPadding: 20
}
MediumText {
anchors.verticalCenter: parent.verticalCenter
width: parent.width / 3
text: model.area
horizontalAlignment: Text.AlignRight
rightPadding: 20
}
}
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: 1
visible: model.index !== 0
color: Material.color(Material.Grey)
}
}
}
The Listview rows always scroll behind the header.
So make it opaque (e.g. Rectangle with background instead of item) and increase the z value to have it on top.
For the scrolling use highlightRangeMode, preferredHighlightBegin and preferredHighlightEnd.

Qml Text Size based on Container

I am using Qt Quick to develop an app (Qt 5.8). I have text that appears in multiple places so I created a component to use to display the text. The areas the text can vary in placement and size. How can I adjust my text so that the data displays in 1 line horizontally and all text is the same size if I simply want to display the following?
FLAPS 1
GEAR DOWN
TRIM -1.0
I used Text and was able to get close, however since GEAR DOWN has more characters the text was smaller, than flaps and trim. So I moved on to using Label. Can someone provide better insight on how to have text size based on its container's width or height?
main.qml
import QtQuick 2.6
import QtQuick.Window 2.2
Window {
id: windowRoot
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Rectangle{
height: windowRoot.height * .80
width: windowRoot.width * .80
color: "green"
anchors.centerIn: parent
Rectangle {
id: rect1
opacity: .5
anchors.top: parent.top
anchors.left: parent.left
color: "lime"
border.color: "orange"
height: parent.height * 1/2
width: parent.width * 1/2
TextHolder {
anchors.top: parent.top
anchors.left: parent.left
width: parent.width * 1/4
height: parent.height
}
}
Rectangle {
id: rect2
anchors.top: parent.top
anchors.left: rect1.right
color: "yellow"
border.color: "blue"
height: parent.height * 1/2
width: parent.width * 1/2
}
Rectangle {
id: rect3
anchors.top: rect1.bottom
anchors.left: parent.left
color: "pink"
border.color: "red"
height: parent.height * 1/2
width: parent.width * 1/2
TextHolder {
anchors.top: parent.top
anchors.left: parent.left
width: parent.width * 1/4
height: parent.height * 1/2
}
}
Rectangle {
id: rect4
anchors.top: rect2.bottom
anchors.left: rect3.right
color: "orange"
border.color: "lime"
height: parent.height * 1/2
width: parent.width * 1/2
TextHolder {
anchors.bottom: parent.bottom
height: parent.height * 1/4
width: parent.width * 1/4
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}
TextHolder.qml
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.1
Rectangle {
color: "purple"
border.color: "steelblue"
border.width: 3
property color colorOfText: "white"
property real textSize: 48
Item {
id: inputs
property int flapHndl: 1
property int gearHndl: 1
property real trim: -1.0
}
clip: true
ColumnLayout {
anchors.top: parent.top
width: parent.width
height: parent.height
spacing: 5
Label {
id: flapLabel
text: "FLAPS " + inputs.flapHndl
color: colorOfText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: textSize
fontSizeMode: Text.HorizontalFit
Layout.fillWidth: true
}
Label {
id: gearLabel
text: {
if (inputs.gearHndl === 1)
return "GEAR DOWN"
else
return "GEAR UP"
}
color: colorOfText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: textSize
fontSizeMode: Text.HorizontalFit
Layout.fillWidth: true
}
Label {
id: trimLabel
text: "TRIM " + inputs.trim.toFixed(1)
color: colorOfText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: textSize
fontSizeMode: Text.HorizontalFit
Layout.fillWidth: true
}
}
}
Can someone provide better insight on how to have text size based on
its container's width or height?
For evaluating the text width and height we can definitely use QML type TextMetrics and having the metrics we can then attempt to fit the text in. If the text still won't fit we can then try to adjust the font size. For that, some logic might need to be implemented with JavaScript. So, the below code is an example of the "feedback" type of solution.
Rectangle {
property string textToShow
property int widthLimit: 400
onTextToShowChanged: {
while (txtMeter.width > widthLimit) {
txtMeter.font.pixelSize --;
}
}
TextMetrics {
id: txtMeter
font.family: "Courier"
font.pixelSize: 25
text: textToShow
}
Text {
font: txtMeter.font
text: textToShow
}
}
P.S. This is just a sketchy idea and your actual implementation may differ
There is fontSizeMode property of Text
Text {
id: goToParentFolderText
anchors.fill: parent
font.family: fontAwesomeSolid.name
text: "\uf060"
fontSizeMode: Text.Fit
font.pointSize: 100
color: Material.accent
}
I was able to get #Alexander V's answer to work, with a minor change. The outer textToShow property was processing its update before the TextMetrics block was updated (which caused the width calculation to be incorrect). You can fix this issue by triggering onTextChanged inside the TextMetrics blocks instead.
Rectangle {
property string textToShow
property int widthLimit: 400
TextMetrics {
id: txtMeter
font.family: "Courier"
font.pixelSize: 25
text: textToShow
onTextChanged: {
while (txtMeter.width > widthLimit) {
txtMeter.font.pixelSize --;
}
}
}
Text {
font: txtMeter.font
text: textToShow
}
}

QML combobox styling issue in QtQuick.Controls 2.2

I'm beginner. I'm trying to use combobox to populate a list of elements, but when I tried to style there is some problem while displaying text.
Here is the code:
import QtQuick 2.7
import QtQuick.Controls 2.2
Item {
property string btntext : "First"
signal dropDownIndexChanged(int index)
id: mainDropDown
ListModel{
id: modelList
ListElement{ text: "First" }
ListElement{ text: "Second" }
ListElement{ text: "Third" }
}
ComboBox {
id: comboButton
width: parent.width
height: parent.height
model:modelList
currentIndex: 0
editText : btntext
Image {
id: imageMainButton
x: 119
anchors.top: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 9
anchors.topMargin: -7
fillMode: Image.Tile
sourceSize.height: 25
sourceSize.width: 25
source: "<some image>"
}
delegate: ItemDelegate {
id:itemDelegate
width: comboButton.width
background:Rectangle{
gradient: Gradient {
GradientStop {
position: 0.0
color: itemDelegate.down ? "white" : "blue"
}
GradientStop {
position: 1.0
color: itemDelegate.down ? "yellow" : "orange"
}
}
}
contentItem: Text {
text: modelData
elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
font.pointSize: 11
font.family: "Arial"
color: itemDelegate.down ? "black" : "white"
}
highlighted: comboButton.highlightedIndex === index
}
indicator: Canvas {
}
//When this is added combo box text disapears or will be empty until something else is selected from the dropdown.
contentItem: Text {
text: comboButton.displayText
anchors.centerIn: parent
//font: comboButton.font
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
renderType: Text.NativeRendering
anchors.left : parent.left
anchors.leftMargin: 10
font.family: "Verdena"
font.pointSize: 12
font.bold: true
color: "white"
}
background: Rectangle {
implicitWidth: 120
implicitHeight: 40
radius: 2
color : "white"
//height:100
smooth: true
//border.width: 1
border.color: "white"
}
popup: Popup {
y: comboButton.height
width: comboButton.width -5
//implicitHeight: contentItem.implicitHeight -1
padding: 1
background: Rectangle {
border.color: "black"
radius: 2
color : "white"
}
contentItem: ListView {
//clip: true
implicitHeight: contentHeight
model: comboButton.popup.visible ? comboButton.delegateModel : null
currentIndex: comboButton.highlightedIndex
interactive: false
}
}
onCurrentIndexChanged:
{
btntext = mainDropDown.get(currentIndex).text
dropDownIndexChanged(currentIndex)
console.log(btntext ,currentIndex)
}
}
}
1) As mentioned above why does combobox text is not displayed until I select an item from the drop down?
2) The selected index/item is not highlighted at all.
1) As mentioned above why does combobox text is not displayed until I select an item from the drop down?
This is because your background Rectangle color is "White", same as your Text color ("white" is default color).
2) The selected index/item is not highlighted at all.
This is because inside delegate (id: itemDelegate), you are changing color based on itemDelegate.down condition. Change this to itemDelegate.highlighted.

Resources