Show only part of Qt Qml Drawer - qt

I want to show only half of a QML Drawer. The idea is to keep some important information in the visible part of the drawer and then let the user show the full drawer with more information.
From the documentation I thought that the
position property should be suitable for this:
Drawer {
modal: false
interactive: false
position: 0.5 // does not work
}
But setting the position does not have an effect. Is it possible to show only a part of the drawer?

As mentioned in my comment, you may want to turn your concept inside out, and have the Drawer inherit its size from its contents, and have the contents change, rather than hardcode its size and manipulate its position.
Here is a full example that shows the idea. The drawer contains a RowLayout which contains "info" and "extra info" - the extra info's visibility is toggled via interaction, and thus changes the size of the drawer, which always stays at the 100% open position, but changes width automatically.
import QtQuick 2.12
import QtQml 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
Window {
id: root
width: 640
height: 480
visible: true
Drawer {
id: drawer
height: root.height
// width automatically derived from RowLayout child's implicitWidth
onClosed: detailed.visible = false
RowLayout {
height: parent.height
spacing: 0
Rectangle {
id: detailed
color: "lightcyan"
Layout.fillHeight: true
Layout.preferredWidth: 200
visible: false // when not visible, this does not add to the RowLayout's implicitWidth
Text {
anchors {
centerIn: parent
}
text: "Extra Info\n Click to close"
}
MouseArea {
anchors {
fill: parent
}
onClicked: {
detailed.visible = false
}
}
}
Rectangle {
color: "lightpink"
Layout.fillHeight: true
Layout.preferredWidth: 200
Text {
anchors {
centerIn: parent
}
text: "Regular Info\n Click to open extra info"
}
MouseArea {
anchors {
fill: parent
}
onClicked: {
detailed.visible = true // toggling visibility automatically makes the Drawer wider
}
}
}
}
}
MouseArea {
id: mouse
anchors {
fill: parent
}
onClicked: {
drawer.open()
}
}
Text {
anchors {
centerIn: parent
}
text: "Click to open drawer"
}
}

Related

Looking for alternate function to QML ListView's itemAtIndex due to version conflict

I'm using Qt 5.12, so I can't access ListView's itemAtIndex which was introduced in Qt 5.13.
I can't upgrade Qt due to my project/platform related restrictions. Is there a way to find the item at a given index for ListView with the Qt versions prior to 5.13?
Otherwise, is there a way to get mouse positions of an item based on index?
I'm having a listview with adjacent items having different width(alternate items have same width). I'm trying to access listview's item which is of less width compared to the adjacent item. The space between two items in the above picture is also an item which is marked as dummy. I'm able to get the index of each item (both actual & dummy), but the x position I get seems to be incorrect as the rectangle cursor is not getting placed in the intended item's position.
Please suggest alternatives that gives the similar functionality as itemAtIndex. Thanks.
In the following example, I declare a MouseArea in each delegate. So, once the mouse hovers over that delegate, we trigger MouseArea.onEntered and can know which item, because that delegate will have the corresponding index value:
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
Page {
background: Rectangle { color: "#848895" }
ColumnLayout {
anchors.fill: parent
ListView {
id: listView
Layout.fillWidth: true
Layout.preferredHeight: 150
model: 20
orientation: ListView.Horizontal
delegate: MyDelegate { }
ScrollBar.horizontal: ScrollBar {
height: 20
policy: ScrollBar.AlwaysOn
}
highlight: Item {
z: 2
Rectangle {
width: 10
height: parent.height
color: "lightsteelblue"
border.color: "black"
}
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
Frame {
anchors.centerIn: parent
background: Rectangle { }
Text {
text: qsTr("ListView.currentIndex = %1").arg(listView.currentIndex)
}
}
}
}
}
// MyDelegate.qml
import QtQuick
import QtQuick.Controls
Rectangle {
property ListView listView: ListView.view
width: 120
height: listView.height - 20
implicitWidth: width
implicitHeight: height
color: "transparent"
Rectangle {
border.color: "grey"
color: "white"
y: 20
height: parent.height - y * 2
width: parent.width
Text {
anchors.centerIn: parent
text: qsTr("Item %1").arg(modelData + 1)
}
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: listView.currentIndex = index
}
}
You can Try it Online!

How to align button text

I have a button with some text which is normally centered, but I want this text to align to the left. I have tried some things but they don't seem to work. Is this possible, if yes how can it be done?
import QtQuick 2.15
import QtQuick.Window 2.2
import QtQuick.Controls 2.15
Window {
id: window
visible: true
height: 400
width: 400
Button {
id: button
text: "Align me to the left"
//horizontalAlignment: Text.AlignLeft
width: parent.width
height: 30
flat: true
onClicked: {
console.log("You clicked me")
}
}
}
To customize a Button, you can override the contentItem and/or background properties. If you want left-aligned text, just use the contentItem to create a Text object that looks the way you want it.
Button {
id: button
contentItem: Text {
text: button.text
font: button.font
horizontalAlignment : Text.AlignLeft
}
...
}
Button {
id: button
contentItem: Text {
text: "Align me to the left"
horizontalAlignment : Text.AlignLeft
}
width: parent.width
height: 30
flat: true
onClicked: {
console.log("You clicked me")
}
}

QML: horizontal flickable visually lingers in StackView

Suppose you have a long horizontal content, so you put it in flickable for your user to swipe through. This might be a picture or a graph or something else. When the content is swiped right so that it's left side is hidden, and you pop the page from stack, a stack animation occurs where all the content is moved right. However, the before hidden part of flickable content then slides to the right also and becomes visible until the animation is over. I want to find a way to prevent this.
Here is the picture of a red rectangle lingering, carefully captured at 25 frames per second:
Here is the minimal example code to illustrate the problem:
import QtQuick 2.9
import QtQuick.Controls 2.2
ApplicationWindow {
id: window
visible: true
width: 640
height: 480
header: ToolBar {
contentHeight: toolButton.implicitHeight
ToolButton {
id: toolButton
text: "<"
onClicked: {
stackView.pop()
}
}
}
StackView {
id: stackView
initialItem: pageZero
anchors.fill: parent
}
Component {
id: pageZero
Column {
Label {
text: "Page zero"
}
Button {
text: "next"
onClicked: { stackView.push(pageOne) }
}
}
}
Component {
id: pageOne
Flickable {
height: 200
width: 200
contentHeight: 200
contentWidth: 300
Rectangle {
height: 200
width: 300
color: "red"
}
}
}
}
The question is, what handlers should i put to hide the flickable before the animation starts?
Alright, i found how, actually this solution wasn't that hard. (= What i need to do is to have my flickable hidden during the transition, and also shown after the transition has ended, so I add the two lines:
Flickable {
height: 200
width: 200
contentHeight: 200
contentWidth: 300
// watch this next line
StackView.onDeactivating: {rect.visible = false}
StackView.onActivating: {rect.visible = true}
Rectangle {
id: rect
height: 200
width: 300
color: "red"
}
}

Align and size buttons to the textbox above it

I am using Qt qml to design a very simple user interface. The QML is as follows:
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
Rectangle {
width: 800; height: 600
ColumnLayout {
anchors.centerIn: parent
spacing: 25
TextField {
placeholderText: qsTr("User name")
width: 200
}
TextField {
placeholderText: qsTr("Password")
width: 200
echoMode: TextInput.Password
}
RowLayout {
Button {
text: "Log In"
}
Button {
text: "Cancel"
}
}
}
}
What I am trying to do is ensure that both the buttons take the same size and they occupy the same amount of space horizontally as the TextField components. Is it possible to achieve this using QML?
Just resize the Layout to the wanted width and use the attached property Layout.fillWidth: true to expand / reduce the size of the Item. Just updated your example to illustrate:
import QtQuick 2.0
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
Rectangle {
width: 800; height: 600
ColumnLayout {
width: 200
anchors.centerIn: parent
spacing: 25
TextField {
placeholderText: qsTr("User name")
Layout.fillWidth: true
}
TextField {
placeholderText: qsTr("Password")
Layout.fillWidth: true
echoMode: TextInput.Password
}
RowLayout {
Button {
text: "Log In"
Layout.fillWidth: true
}
Button {
text: "Cancel"
Layout.fillWidth: true
}
}
}
}
PS: It's not needed in a child-layout where Layout.fillWidth and Layout.fillHeight is set by default.
If you have any questions on that feel free to ask...
Yes, you just need to give an id to your TextField
TextField {
id: myTextField
...
}
and reference the width of your TextField in your Button:
Button{
...
width: myTextField.width
}

How to make image to fill qml controls button

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
}

Resources