I am designing a simple high score in qml. I have decided to use a GridLayout inside a GroupBox for displaying some text. I dont know why, but I cannot change the width of the text. I have tried margins, but they also dont work. Right now the text crashes into the border of the GroupBox. (I want the GroupBox inside the Item because I'm going to add other things in it like a button later.)
Item {
id: highscores
width: 450
GroupBox {
id: highscore_box
title: qsTr("GroupBox")
anchors.centerIn: parent
width: parent.width
height: 450
background: Rectangle {
y: highscore_box.topPadding - highscore_box.padding
width: parent.width
height: parent.height - highscore_box.topPadding + highscore_box.padding
color: "transparent"
border.color: "white"
border.width: 5
radius: 10
}
label: Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.top
anchors.bottomMargin: -height/2
color: "white" //set this to the background color
width: parent.width * 0.6
height: box_title.font.pixelSize
Text {
id: box_title
text: qsTr("High Scores")
anchors.centerIn: parent
font.pixelSize: 32
font.family: "Super Mario Bros."
}
}
contentItem: GridLayout {
id: highscore_grid
columns: 3
//width: ?????
Text {text: "Place";font.bold: true; color: "white";
font.family: "Super Mario Bros."; font.pixelSize: 30}
Text {text: "Player";font.bold: true; color: "white";
font.family: "Super Mario Bros."; font.pixelSize: 30}
Text {text: "Time";font.bold: true; color: "white";
font.family: "Super Mario Bros."; font.pixelSize: 30}
Text {text: "1st";font.bold: true; color: "white";
font.family: "Super Mario Bros."; font.pixelSize: 20}
Text {text: "--";font.bold: true; color: "white";
font.family: "Super Mario Bros."; font.pixelSize: 20}
Text {text: "--";font.bold: true; color: "white";
font.family: "Super Mario Bros."; font.pixelSize: 20}
}
}
}
When working with layouts, you can't use the standard anchor calls. You will instead need to use these following calls to manipulate your grid layout.
In addition, when you declare a layout, you need to specify what space it will occupy. You could use something like
anchors.fill: parent
Afterwards, you may need to also specify the space the objects inside of the gridlayout will take up. Yet again, don't use standard width/len calls but the Layout.XXXX calls.
Layouts are great for building fluid and dynamic screens, but they can be little rascals sometimes. Nesting Layouts is extremely beneficial. I personally use many-many layers deep layouts. Gl!
I would recomend creating a 'practice' QML file wherein you create a gridlayout with many objects inside of it. Rectangles/buttons/more layouts. Get comfy with it. Once you have more understanding of layouts, then try and apply it to your existing problem which involves MVC.
Related
I was working with a GridView in QML. When I click on an element, I want to following highlight to happen:
However, my problem is that I want the blue color to appear below the delegate (not in the white area but still visible on the transparent side part) while the checkmark appears above (so it is visible). I have tried playing around with the z values so that the lowest z should be the blue rectangle, the middle should be the white rectangle part of the delegate, and the highest should be the check mark but i can't seem to make it work. Either the highlight or the delegate has to be on top. Does anyone know any way I can fix this so that it works correctly?
Code for highlight:
highlight:
Rectangle {
z:5
color: "steelblue"; radius: 5; opacity: 0.5
Image{
z:8
id: checkMark
visible: found;
x: parent.width-8-width
y: 8
width: 40;
height: 40;
source: "file:///Users/arjun/Documents/CompetitiveBall/images/checkMark.png"
}
}
Code for delegate:
Component {
id: contactsDelegate
Rectangle{
width: grid.cellWidth
height: grid.cellHeight
color: "transparent"
Rectangle {
z:7
width: grid.cellWidth-20
height: grid.cellHeight-20
id: wrapper
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
border.width: 3
border.color: "black"
radius: 5;
Image{
id: mImage
x:parent.x
width: 65
height:65;
source: picSource
}
Text{
width: grid.cellWidth-15
y: mImage.y+mImage.height+4
anchors.horizontalCenter: parent.horizontalCenter
id: nameText
text: name
font.family: "Palatino Linotype"
font.bold: (grid.isCurrentItem===true)?"true":"false"
horizontalAlignment: Text.AlignHCenter
color:"#050027"
}
MouseArea{
anchors.fill: parent
onClicked:{
console.log("Clicked on :" + name)
//what happens when u click
grid.currentIndex=index;
}
}
}
}
}
Since you want part of the highlight to be underneath the delegate and part of it to be on top, you need to break it up into different pieces. I tested the code below with Qt 5.15.0. I made the normal highlight object draw underneath the delegate. Then I added another Rectangle that follows the highlight that draws on top of the delegate.
GridView
{
id: lv
anchors.fill: parent
anchors.margins: 50
cellWidth: 50
cellHeight: 50
model: 30
// By default, highlight draws behind delegates
// (You can specify a positive z-value to make it draw on top)
highlight: Item
{
Rectangle
{
anchors.centerIn: parent
width: 50
height: 50
color: "green"
}
}
delegate: Rectangle
{
width: 30
height: 30
color: "red"
MouseArea
{
anchors.fill: parent
onClicked: lv.currentIndex = index;
}
}
// This will draw on top of the delegates
// (You can change that by specifying a negative z-value.)
Rectangle
{
id: checkbox
x: lv.highlightItem.x - lv.contentX
y: lv.highlightItem.y - lv.contentY
width: 10
height: 10
color: "blue"
}
}
I am not able to increase height of Rectangle (or RowLayout) wrapped around Text item that could dynamically change (chat message for example).
I tried bunch of approaches (Text.paintedHeight, childrenRect ...) but everything looks funky when text is wrapped.
My goal is display chat messages, stretch them according their wrapped text height.
Thanks for any input.
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 900
height: 500
ColumnLayout {
width: parent.width
spacing: 2
RowLayout {
id: rowLayout
spacing: 3
Rectangle {
height: 50
width: 50
color: "red"
}
Rectangle {
id: rectangle
width: 50
color: "green"
Layout.fillHeight: true
Layout.fillWidth: true
Text {
id: element
text: "If the GridLayout is resized, all items in the layout will be rearranged. It is similar to the widget-based QGridLayout. All visible children of the GridLayout element will belong to the layout. If you want a layout with just one row or one column, you can use the RowLayout or ColumnLayout. These offer a bit more convenient API, and improve readability.\n\nBy default items will be arranged according to the flow property. The default value of the flow property is GridLayout.LeftToRight.\n\nIf the columns property is specified, it will be treated as a maximum limit of how many columns the layout can have, before the auto-positioning wraps back to the beginning of the next row. The columns property is only used when flow is GridLayout.LeftToRight."
anchors.rightMargin: 10
anchors.leftMargin: 10
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
wrapMode: Text.WordWrap
clip: false
font.pixelSize: 12
}
}
}
}
}
You have to specify the implicitHeight and implicitWidth for Rectangle (and Item for that matter).
Rectangle {
id: rectangle
width: 50
color: "green"
Layout.fillHeight: true
Layout.fillWidth: true
implicitWidth: element.implicitWidth
implicitHeight: element.implicitHeight
Text {
id: element
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
wrapMode: Text.WordWrap
clip: false
font.pixelSize: 12
}
}
Please note that your current setup with anchors.margins is slightly conflicting here, since that is not counted in the implicitHeight/Width, so I left them out.
Another option would be to set the background for a Label (from QtQuick.Controls) to your desired Rectangle, that will then be stretched properly:
Label {
leftPadding: 10
rightPadding: 10
...
background: Rectangle {
color: "green"
}
}
In my opinion this would give you easier control about the position of your text.
I'am using Qml to develop a system, I want to change TableViewColumn's default height and its border style. I just want to show the bottom/right borders, to look like table.
In your TableView you could define custom itemDelegate with borders and desired height https://doc.qt.io/qt-5/qml-qtquick-controls-tableview.html#itemDelegate-prop
TableView {
itemDelegate: Rectangle {
height: 30 // put your height here
border.color: "black"
border.width: 1
Text {
anchors.verticalCenter: parent.verticalCenter
color: styleData.textColor
elide: styleData.elideMode
text: styleData.value
}
}
}
You can use rowDelagate property of TableView component.
TableView {
id: idReadDataTableView
anchors.fill: parent
rowDelegate: Rectangle {
width: parent.width
height: 40
}
}
We are developing an application on IMX6 using Qt 5.3.2. The Qt libraries are provided by Yocto.
Our requirement is to list items inside a drop down menu using a particular background style. For this purpose we are using ComboBox provided by Qt Quick Controls and QtQuick.Controls.Styles for customizing the drop down background style. We are using MenuStyle component to customize the drop down.
When we apply the styles, we observed that the drop down bottom border does not close.
Please use the following link to view the picture.
We are not facing this issue in the Desktop. We tried running the same application on Ubuntu 12.04.
https://www.dropbox.com/s/33a57jaxs452c4r/IMX6.JPG?dl=0
https://www.dropbox.com/s/cmvvf3ytxg615q8/Ubuntu.JPG?dl=0
Also, below I've listed the qml code which we used for Customizing the drop down.
ComboBox {
id: comboFilterBy
x: 10
y: 130
z:1
width: 285
height: 39
model : eventFiltersList
Rectangle {
id: arrow
anchors.right: parent.right
width: 20; height: parent.height
border.color: "black"
border.width: 1
Image {
id: arrowIcon
// anchors.fill: parent
width: 10
height: arrow.height
anchors.centerIn: parent
clip: true
smooth: true
fillMode: Image.PreserveAspectFit
source: "images/dropDownArrow.png"
}
}
style: ComboBoxStyle {
background:
Rectangle {
color: "#FFFFFF"
border.width: 1
border.color: "black"
antialiasing: true
}
label: Text {
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.left
font.pointSize: 19
font.family: "WenQuanYi Micro Hei Mono"
color: "black"
text: control.currentText
}
// drop-down customization here
property Component __dropDownStyle: MenuStyle {
__maxPopupHeight: 240
__menuItemType: "comboboxitem"
padding.bottom : getPaddingLength(1)
frame: Rectangle { // background
color: "#fff"
border.width: 1
}
itemDelegate.label: // an item text
Text {
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pointSize: 19
font.family: "WenQuanYi Micro Hei Mono"
color: "black"
text: styleData.text
}
itemDelegate.background: Rectangle { // selection of an item
color: styleData.selected ? "#5692c4" : "transparent"
}
__scrollerStyle: ScrollViewStyle { }
}
}
Any help is greatly appreciated.
--Narayanan K
Is possible to create a custom style file in QT and apply it for all QML files (like CSS does applies to HTML )?
Is there any "class" declaration for QML ?
If you want to declare a "class" in QML you have to create new QML file. Its name must begin with a capital letter. You can also create custom objects using C++ but probably that is not what you are looking for.
Let's say you want to create custom Text element so the text is always centered and fits the given dimensions. So you create a file named CustomText.qml and write:
/* CustomText.qml file */
import QtQuick 2.0
Text {
id: customText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
clip: true
fontSizeMode: Text.Fit
font.pixelSize: height
wrapMode: Text.WordWrap
minimumPixelSize: 3
color: "black"
/* using these lines you can set custom font loaded from a file */
// font.family: customFont.name
// FontLoader {
// id: customFont
// source: "qrc:/myCustomFont.ttf"
// }
}
Now you can use it like this:
/* main.qml file */
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
visible: true
width: 300
height: 300
Rectangle {
id: rectangle1
color: "lightgrey"
x: 5
y: 5
width: 200
height: 50
CustomText {
anchors.fill: parent
text: "testing custom text object"
}
}
Rectangle {
id: rectangle2
color: "lightgrey"
anchors.left: rectangle1.left
anchors.top: rectangle1.bottom
anchors.topMargin: 5
width: 50
height: 50
CustomText {
anchors.fill: parent
text: "testing custom text object"
}
}
Rectangle {
id: rectangle3
color: "lightgrey"
anchors.left: rectangle2.left
anchors.top: rectangle2.bottom
anchors.topMargin: 5
width: 100
height: 100
CustomText {
anchors.fill: parent
text: "testing custom text object"
}
}
}
That is how it would look like: