QML: button with image and text underneath - qt

I am trying to create a button like control in QML which displays an image and also some text under it. My current attempt stands as follows:
Item {
id: button
width: 30
height: 100
property alias text: buttontext
signal clicked
Image {
id: visualImage
anchors.fill: parent
source: "qrc:/images/test.png"
}
Text {
id: buttontext
font.bold: true
text: "Test"
}
}
This has a lot of problems unfortunately. So, at the moment, I am specifying the width and height of the item but this should be calculated based on the width and height of the image and the text. Also, the text is shown at the top and inside the image where I would like to position the text under the image, centered with image horizontally with some margins.

You must use anchors in the Image and in the Text. Example:
Item {
id: button
width: 30
height: 100
property alias text: buttontext
signal clicked
Image {
id: visualImage
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: buttontext.top
source: "qrc:/images/test.png"
}
Text {
id: buttontext
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
font.bold: true
text: "Test"
}
}

Since QtQuick.Controls 2.3 (Qt 5.10), display property was introduced:
This property determines how the icon and text are displayed within the button.
For your case it's AbstractButton.TextUnderIcon

Something I have done in the past as a workaround for this,
create a Rectangle{……} which holds all the 'Button' items, (Text/Image Ect),
It may not be the prettiest way but there is a few variations
Create the 'Image' and 'text' externally (photoshop whatever you choose) then fill your Rectangle with the content, then also set a MouseArea { onClicked {……}} event to that,
Make a Column/Grid/Row within the Rectangle and position your items using that method

Related

Adding text to a RoundButton in QT 5.15

Trying to add text to a round button. Gives the error 'Cannot assign to non-existent property: text'.
RoundButton {
id: circ1
text: qsTr("RoundButton")
anchors.right: parent.right
anchors.rightMargin: 1.0 * ScreenTools.defaultFontPixelWidth
anchors.topMargin: 1.0 * ScreenTools.defaultFontPixelHeight
anchors.top: parent.top
Layout.alignment: Qt.AlignHCenter
//radius: 120
width: 60
height: 60
contentItem: Text {
text: "Plan"
}
//font.pointSize: ScreenTools.smallFontPointSize * ScreenTools.smallFontPointRatio
}
Code works as expected without the text property. It also works for a regular button with the text property. I was under the impression a roundbutton should work identical to a regular button. Any idea where i am going wrong?
I wasn't able to recreate your issue. A couple things:
You have Layout.alignment and anchors.*** These are incompatible I
believe
The text of roundButton is not used as you have set the
contentItem to a static Text{} Item rather setting you text within it to
circ1.text

How to setup ListView that hightlight fits always into it

I have a vertical ListView with a lot elements. When an element gets clicked a Rectangle pops up under it as highlight.
This doesnt work for the last elements in the ListView, as can be seen in the image.
How do I setup ListView, that a highlight pushes all elements up.
What I have:
What I want:
I could solve my issue by expanding the selected delegates height for the while it is selected. Furthermore you have to set the hightlight's y explicitly.
ListView{ id:listView
property var someHeight: 100
delegate:Item{
id: delegate
Connections{
target: listView
function onCurrentIndexChanged(){
if(index==listView.currentIndex)
delegate.height=someHeight+listView.highlightItem.childrenRect.height
else
delegate.height=someHeight
}
}
}
}
highlight:Item{
z:10
Rectangle{
id:highlightRect
anchors.left:parent.left
anchors.leftMargin: smallMargin
anchors.right: parent.right
anchors.rightMargin: smallMargin
y: someHeight;
height:someHighlightHeight
}
}
}

shift the textfield edit area

I have a qml based application where I have a search field. The field also has an icon to indicate it is a search box. The problem is that when I type the text it overlaps the icon and I would like to basically constrain the text input area to the text field which does not contain the image.
The qml code is as follows:
TextField {
id: searchBox
font.pixelSize: 18
background: Rectangle {
radius: 6
border.color: "#707070"
border.width: 1
Image {
source: "../images/search.png"
anchors.left: parent.left
anchors.leftMargin: 12
anchors.verticalCenter: parent.verticalCenter
}
}
}
The resulting component is rendered as follows:
As you can see the text input area overlaps with the image. Is there a way to ensure that the text input area gets clipped or in this case shifted to the right and that the user cannot add text where the image is rendered?
You can use padding properties
rightPadding: 30
leftPadding: 24

How I can dropdown options when I check on checkbox?

I have one Checkbox with onCheckedChanged handler and what I want is, when the Checkbox is checked, dropdown a menu with several texts and text fields. I have the following code:
CheckBox {
id: box
onCheckedChanged: {
// TODO here to dropdown a menu with settings
}
}
I have texts and text fields like the following:
Component {
id: label
Text {
color: "red"
antialiasing: true
smooth: true
}
}
I'm a newbie in QML so please be patient.
You didn't really say where this menu is located, if it's floating or if it is to just appear maybe displacing other elements on the view. Anyway, to anwser your question, you can achieve what you're asking by setting the height of your 'menu' to zero then, when the CheckBox is checked, setting it to however tall you want it to be. To make the menu grow smoothing you can use a NumberAnimation.
You can change your onCheckedChanged() slot to look like this:
onCheckedChanged: {
menu.height = checked ? 100 : 0
}
and add the following, as a child of your menu element:
Behavior on height { NumberAnimation {...} }
to make the menu's height grow from 0 to 100 over a period of time to make it grow smoothly.
Another approach, which I'd prefer, is to use States with a Transition (instead of a Behavior).
Here is an example of a 'menu' which, when the CheckBox is checked, will slide out from beneath the CheckBox:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
Rectangle {
id: checkboxContainer
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: 100
color: "pink"
CheckBox {
id: menuCheckBox
anchors.centerIn: parent
text: qsTr("Click Me")
}
}
Rectangle {
id: menu
anchors.top: checkboxContainer.bottom
anchors.left: parent.left
anchors.right: parent.right
height: 0 //This is the default value when the 'default' state is active. That is whenever we're not in the "openState"
clip: true // this hurts rendering performance a bit but is required to make sure child elements don't exceed the bounderies of this object (so when height is zero you don't see the text)
color: "lightblue"
states: [
State {
name: "openState"
when: menuCheckBox.checked // This state is only active when the check box is checked. When you uncheck the check box we move to the 'default' state (which sets the menu's hight back to zero)
PropertyChanges {
target: menu
height: 100
}
}
]
transitions: Transition {
NumberAnimation {
property: "height"
duration: 350 //This means when the height property is changed it will take 350ms to move from what its at to what your changing it to (i.e. 0 to 100 or 100 to 0).
easing.type: Easing.InOutQuad
}
}
Text {
anchors.centerIn: parent
color: "red"
antialiasing: true
smooth: true
text: qsTr("HELLO")
}
}
}
I hope this answers your question.

How to correctly change the row height of a TableView?

Window {
id: uninstallWindow
width: 640
height: 480
property variant pluginData;
TableView {
id:_pluginTable
anchors.right: parent.right
anchors.rightMargin: 0
anchors.left: parent.left
anchors.leftMargin: 0
anchors.bottom: parent.bottom
anchors.bottomMargin: 43
anchors.top: parent.top
anchors.topMargin: 0
model: pluginData
itemDelegate: Text {
text: modelData
font.pixelSize: 24
}
TableViewColumn {
}
}
}
It's taken me hours just to get this far, and I feel like this should be a relatively simple operation, so why is it so hard? As you can see I change the font size of the items in the table because they were too small by default. This simply caused them to get clipped by the non-changing row size. I've tried
Setting a rowDelegate object (but this causes loss of all other styling info that is there by default like background, selection color, etc and I don't know how to specify it otherwise)
Setting a custom model object based on QAbstractListModel / QAbstractTableModel (for some reason only known to Qt, the "data" function was never ever called...)
Setting a custom item delegate (it seems that the height is no longer controlled from this object though)
What hoops do I need to jump through to get the rows to change their size?
As the Asker already wrote, custom row height can be achieved using the rowDelegate, but this discards the default style. The default style can be restored using the SystemPalette.
rowDelegate: Rectangle {
height: 30
SystemPalette {
id: myPalette;
colorGroup: SystemPalette.Active
}
color: {
var baseColor = styleData.alternate?myPalette.alternateBase:myPalette.base
return styleData.selected?myPalette.highlight:baseColor
}
}
This restores the default background color of the rows (including alternating the row colors when desired) and the color of the selected rows, which seems to be all that is needed.
The following just worked like a charm for me in Qt 5.10:
rowDelegate: Item { height: 30 }
I do the actual styling (fonts/colors) in itemDelegate (and in headerDelegate) and provide content by TableViewColumns (with and without delegates of their own).
To change the row height you need to use rowDelegate. For example:
rowDelegate: Rectangle{
width: childrenRect.width
height: 40
}
To change tableview height you can use Layout.preferredHeight. For example:
Layout.preferredHeight: 300

Resources