How to make image to fill qml controls button - qt

I want icon to fill Button. Here is code:
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Window 2.2
Window{
id: root
title: "settings"
flags: Qt.Dialog
minimumHeight: 700
minimumWidth: 700
maximumHeight: 700
maximumWidth: 700
ColumnLayout{
id: columnLayout
anchors.fill: parent
RowLayout{
Button{
iconSource: "images/1x1.png"
checkable: true
checked: true
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Button{
iconSource: "images/1x2.png"
checkable: true
checked: false
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Button{
iconSource: "images/2x1.png"
checkable: true
checked: false
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Button{
iconSource: "images/2x2.png"
checkable: true
checked: false
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
}
Rectangle{
visible: true
implicitHeight: 600
implicitWidth: 700
color: "red"
}
}
}
Button size is 100*100 pixels but image size is much lower. How to make image to be as big as button

It really depends on what you want to achieve. IMO, there are three solutions here:
1) If you need an image as a button, just use Image with a MouseArea filling it:
Image {
source: "http://images5.fanpop.com/image/photos/27500000/Cool-beans-azkaban-27533920-200-200.gif"
MouseArea {
anchors.fill: parent
onClicked: {
console.info("image clicked!")
}
}
}
2) If you want to use a button with an image, redefine the label property of the style, as follows:
Button{
width: 200
height: 200
style: ButtonStyle {
label: Image {
source: "http://images5.fanpop.com/image/photos/27500000/Cool-beans-azkaban-27533920-200-200.gif"
fillMode: Image.PreserveAspectFit // ensure it fits
}
}
}
This way you can fit any image in the Button and the small padding to the borders allows you to see when the button is clicked/checked. Mind that, by using ButtonStyle, you lose the platform style.
3) If you really want to use the Button and make it look like an Image follow the smart approach proposed by Mitch.

If you don't mind using private API, there's the padding property:
import QtQuick 2.4
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Item {
width: 200
height: 200
Button {
iconSource: "http://www.sfweekly.com/imager/the-exhikittenist-cattown-cat-pics-and-m/b/square/3069319/58c8/WikiCat.jpg"
anchors.centerIn: parent
style: ButtonStyle {
padding {
left: 0
right: 0
top: 0
bottom: 0
}
}
Rectangle {
anchors.fill: parent
color: "black"
opacity: parent.pressed ? 0.5 : 0
}
}
}
Looking at ButtonStyle.qml:
/*! The padding between the background and the label components. */
padding {
top: 4
left: 4
right: control.menu !== null ? Math.round(TextSingleton.implicitHeight * 0.5) : 4
bottom: 4
}

If you want the image will fill the button :
Button{
Image {
anchors.fill: parent
source: "images/1x1.png"
fillMode: Image.Tile
}
checkable: true
checked: true
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
or some another fillMode, as you need

I have gone through same problem stated here. thanks a lot for different solutions. But the one that #folibis suggested finally gave a platform looked (flat in windows 10) button with my svg image. But it does work directly well. three reasons:
1. The image was tightly fit with button.To keep like an icon, I used a FLAT groupbox.
2. fillmode tile is not appropriate when we look for simple iconic image on a button. I have changed it to PreserveASpectFit.
3. checkable and checked properties were not intended for normal action buttons. But surely the question's code sample has got these.
pl see my code here. may be useful. Once again Thanks to #Folibis
Button {
id: nextButton
GroupBox {
flat: true
anchors.fill: parent
Image {
anchors.fill: parent
source: "qrc:/next.svg"
fillMode: Image.PreserveAspectFit
}
}
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}

Related

QML ColumnLayout does not respect minimumHeight

I always have problems with the layout management of QML. So, I created a very simple QML App to check ColumnLayout. If I shrink the window horizontally, it will stop at the minimumWitdh when 100 is reached.
But if I shrink the window vertically I can shrink the window, so that both rectangles disappear.
What is going wrong? Why is the minimumHeight not respected?
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Layouts 1.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
ColumnLayout {
Rectangle {
color: "red"
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Rectangle {
color: "blue"
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
}
}
folbis is probably right. But I found another solution. It seems the minimumWidth and minimumHeight will calculate an implicitWidth and implicitHeight of the ColumnLayout. So, this in turn can be used as minimumWidth and minimumHeight of the window, like so:
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
minimumHeight: col.implicitHeight
minimumWidth: col.implicitWidth
ColumnLayout {
id: col
Rectangle {
color: "red"
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
Rectangle {
color: "blue"
Layout.minimumWidth: 100
Layout.minimumHeight: 100
}
}
}
This is very weird, when you come from the XAML-world.

How to managment the position of the item in the ListView during the scrolling

I have the list view. When I scroll items the top element can stop any position and can be seen half height. enter image description here
But I need that after scrolling stop the top element can be seen full height.enter image description here
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Scroll")
ColumnLayout {
anchors.fill: parent
RowLayout {
id: buttonsRow
Button {
text: "Open dump file"
}
Button {
text: "Copy raw data to clipboard"
}
}
ListView {
id: listView
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
model: 100
clip: true
delegate: ItemDelegate {
text: modelData
Rectangle
{
width: parent.width - 5
height: parent.height - 5
color: "green"
}
}
Layout.fillWidth: true
Layout.fillHeight: true
ScrollBar.vertical: ScrollBar {}
}
}
}
Use the snapMode property:
ListView {
snapMode: ListView.SnapToItem
// ...
}

TextArea problematic background QML QT

Trying different code combinations and partially solving my problem I came across a behavior that I can not quite explain. So to the point, When I create a simple TextArea without Scrollview it looks like this:
RowLayout {
id: rowLayout
Rectangle{
height: 50
width: 295
TextArea {
id: textArea
text: (" message...")
wrapMode: Text.WrapAnywhere
anchors.fill: parent
}
}
Text area creates a default background. And now I want to do TextArea with ScrollView ALSO with the default TextArea background but it comes out something like that :
RowLayout {
id: rowLayout
Rectangle{
height: 50
width: 295
ScrollView {
id: scrollView1
anchors.fill: parent
TextArea {
id: textArea
text: (" message...")
wrapMode: Text.WrapAnywhere
}
}
}
The only chance to set the default TextArea background is set implicitHeight,implicitWidth but then after entering the text into a TextArea until the scrollbar appears, the background extends over the entire length by going behind the other components like this :
RowLayout {
id: rowLayout
Rectangle{
//color: "#00000000"
height: 50
width: 295
ScrollView {
id: scrollView1
anchors.fill: parent
TextArea {
id: textArea
text: (" message...")
wrapMode: Text.WrapAnywhere
implicitHeight: 50
implicitWidth: 295
}
}
}
So the only thing I want is a scrollable textarea but with this black default background and NOT my background which I can do with rectangle.
Can anyone take a look?
Thank you :)
I tried do my best. Check the example below, hope it will help =)
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
width: 400
height: 400
RowLayout {
width: 295
height: 50
anchors.centerIn: parent
ScrollView {
Layout.fillHeight: true
Layout.fillWidth: true
background: Rectangle { color: "black" }
TextArea {
id: messageField
placeholderText: qsTr("message...")
color: "white"
wrapMode: TextArea.WrapAnywhere
}
}
}
}
Result:

How do I make the ListElement not get out of the ListView in QML?

I need some help, i have the following code in QML:
import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Layouts 1.3
Window {
visible: true
width: 500
height: 500
ListModel {
id: modeloDeLista
ListElement{
nombre: "Articulo 1"
precio: 5000
descripcion: "Esto es una descripción"
}
ListElement{
nombre: "Articulo 2"
precio: 8000
descripcion: "Esto es una descripción"
}
ListElement{
nombre: "Articulo 3"
precio: 6000
descripcion: "Esto es una descripción"
}
}
Component{
id: vistaLista
Rectangle{
color: "#333"
width: parent.parent.width
height: 70
RowLayout{
Layout.fillWidth: true;
Layout.fillHeight: true;
Text {
text: qsTr("Nombre: "+nombre)
color: "#fff"
Layout.fillWidth: true;
Layout.fillHeight: true;
}
Text {
text: qsTr("Precio: "+precio)
color: "#fff"
Layout.fillWidth: true;
Layout.fillHeight: true;
}
Text {
text: qsTr("Descripcion: "+descripcion)
color: "#fff"
Layout.fillWidth: true;
Layout.fillHeight: true;
}
}
}
}
Rectangle{
id: contenedor
color: "#ddd"
anchors.centerIn: parent
width: parent.width * 0.9
height: parent.height * 0.9
ListView {
spacing: 10
model: modeloDeLista
delegate: vistaLista
anchors.fill: parent
highlightRangeMode: ItemView.NoHighlightRange
}
}
}
this looks like this:
but when you move with the mouse, you pass the gray area that is assigned to you
How do I make it so that it does not get out of there?
I had to put this to allow me to ask the question, because apparently I had little text and more code, so I can ignore this.
Edit
I want to keep the effect but without turning off the scroll
Edit
Here it leaves the container
This is what I need
How do i do it?
If you want to disable the overshoot effect, as indicated by the docs:
boundsBehavior : enumeration
This property holds whether the surface may be dragged beyond the
Flickable's boundaries, or overshoot the Flickable's boundaries when
flicked.
This enables the feeling that the edges of the view are soft, rather
than a hard physical boundary.
The boundsBehavior can be one of:
Flickable.StopAtBounds - the contents can not be dragged beyond the boundary of the flickable, and flicks will not overshoot.
Flickable.DragOverBounds - the contents can be dragged beyond the
boundary of the Flickable, but flicks will not overshoot.
Flickable.OvershootBounds - the contents can overshoot the boundary
when flicked, but the content cannot be dragged beyond the boundary of
the flickable. (since QtQuick 2.5)
Flickable.DragAndOvershootBounds (default) - the contents can be dragged beyond the boundary of the Flickable, and can overshoot the boundary when flicked.
In your case:
ListView {
[...]
boundsBehavior: Flickable.StopAtBounds
}
Update:
You can set the clip property of the Rectangle to true, in your case:
Rectangle{
id: contenedor
color: "#ddd"
anchors.centerIn: parent
width: parent.width * 0.9
height: parent.height * 0.9
clip:true
ListView {
id: list
spacing: 10
model: modeloDeLista
delegate: vistaLista
anchors.fill: parent
}
}

QML: Attach scrollbar to ListView

I'm having an issue with ListView. ListView is too long and part of it appears outside of the window but I can't attach a scrollbar. I tried many different combination. I think that problem lies in height parameter but if remove it ListView displays only first entry.
Column{
anchors.fill: parent
Row{
id: buttonsRow
Button{
text: "Open dump file"
onClicked: fileDialog.visible = true
}
Button{
text: "Copy raw data to clipboard"
}
}
ListView{
id: listView
anchors.top: buttonsRow.bottom
height: contentHeight
//clip: true
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
interactive: true
model: ListModel{
id: listModel
}
delegate: MDelegate{}
}
}
Is there any way to make it scrollable?
I don't see, in the code you posted, where you've attached a scrollbar at all. You need to actually include a ScrollBar component in your ListView, like this:
ListView {
id: listView
ScrollBar.vertical: ScrollBar {
active: true
}
}
See "Attaching ScrollBar to a Flickable" at https://doc.qt.io/qt-5/qml-qtquick-controls2-scrollbar.html
Setting height to contentHeight is probably the issue. That would make the ListView as high as all of its item's heights combined. The scrollbar only works when the height of the view is less than the height of its contents.
Here's an approach that uses layouts instead:
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.3
ApplicationWindow {
width: 400
height: 300
visible: true
ColumnLayout {
anchors.fill: parent
RowLayout {
id: buttonsRow
Button {
text: "Open dump file"
}
Button {
text: "Copy raw data to clipboard"
}
}
ListView {
id: listView
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds
model: 100
clip: true
delegate: ItemDelegate {
text: modelData
}
Layout.fillWidth: true
Layout.fillHeight: true
ScrollBar.vertical: ScrollBar {}
}
}
}
ScrollBar.vertical:ScrollBar{
id: listView
anchors.right: parent.right
visible: listView.contentHeight > listView.height ? true : false
}

Resources