How to do a QML viewer slide itself into the screen - qt

I plan to add a button on flow1 that will make column slide from right to left very fast so I can change some options and then give it ok so it slides back. It's kinda like when you swipe from left to right on Android and it slides a column for you to make chnges.
As you can see, I placed the column right after the flow1. The plan is to add an animation that makes both viewers slide left until most of the screen is covered by column.
Is this the right way to do it? I don't feel confortable about hiding this off the screen and making them appear.
Is it even possible to animate qt quick positioners?

I think you are looking for the Drawer component (available in Qt 5.7 and greater).
You can control the edge of the window at which the drawer will open from with the edge property.
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
visible: true
Drawer {
id: drawer
width: 0.66 * window.width
height: window.height
// Make drawer comes from the right
edge: Qt.RightEdge
Column {
id: column
// Your column contents
}
}
}

Related

QML Tumbler looses vertical mouse focus

When I create a tumbler widget in QML, I can grab it, and change the contents. As soon as I leave the widget with my mouse in vertical direction, the tumbler stops changing its contents. It works fine if I leave the widget to the left or right. In that case, I can operate the tumbler even when the mouse leaves the QML window.
Is there anything I missed?
Example code:
import QtQuick 2.5
import QtQuick.Controls 2.5
Rectangle {
width: 1000
height: 600
Tumbler {
anchors.centerIn: parent
model: 24
width: 30
height: 100
}
}
I'm using QT 6.2.1 and tried it on Kubuntu 20.04 and Yocto Dunfell.
I tried the same thing with a QML Dial. Herewith I can leave the widget in all directions, and it still reacts to my mouse movement.

QML/Qt: Make displayed text as large as possible depending on the parent containing it

I am trying to make a very simple KDE-Plasma Widget where only a certain number is displayed. I want to make this displayed number have a font size as large as possible depending on the parent containing it.
Here is what it looks right now:
As you can see, the text inside has a lot of space around it. What I actually want it to be is something like the "Date And Time" Widget found in KDE Plasma (my widget is right next to it for comparison):
Here, the time displayed has much lesser space around it while also auto-resizing whenever the panel height is changed.
Here is what the current code looks like:
import QtQuick 2.6
import QtQuick.Layouts 1.0
import org.kde.plasma.components 2.0 as PlasmaComponents
import org.kde.plasma.plasmoid 2.0
Item {
id: main
anchors.fill: parent
Layout.minimumWidth: units.iconSizes.large
Layout.minimumHeight: units.iconSizes.large
Plasmoid.preferredRepresentation: Plasmoid.fullRepresentation
PlasmaComponents.Label {
id: display
anchors {
fill: parent
margins: Math.round(parent.width * 0.1)
}
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
text: foobar
font.pixelSize: 1000;
minimumPointSize: theme.smallestFont.pointSize
fontSizeMode: Text.Fit
font.bold: true
}
Timer {
some stuff
}
}
I tried looking into the code of the above Date and Time widget and wrote down the exact same layouts/controls (which is what you are seeing in the above code) with the same positioning/styling properties and yet I get a lot of space around my text/or the font size continues to remain small.
I tried your code and it resized the font correctly. For the spacing around the text, there are two points:
The spacing on the left and right is easily controlled by adjusting the margins value that you are using. For less space, try Math.round(parent.width * 0.05).
The spacing on the top and bottom is larger because the shape of your parent object is square, while the shape of the text is rectangular. In order to make the text fit the height of the square without exceeding the width of the square, the text would not just need to resize, it would need to be stretched vertically. But QML does not have an easy way to do that, and I doubt that's really what you want anyway.
EDIT:
And if you do want font stretching, I'll point you to this answer.
Thanks to #JarMan's input I was able to realize that my text was being rendered in small font because of lack of space due to the root (item) element being square in shape.
I have now figured that to change the layout sizes of the root element inside the KDE-Plasma panel, one needs to mess with Layout.preferredWidth and Layout.preferredHeight.
Here is what I did:
item {
.
.
Layout.preferredWidth: 150 * units.devicePixelRatio
Layout.preferredHeight: 50 * units.devicePixelRatio
.
.
}
Note: the 150 and 50 values aren't final. It basically gives an idea about the ratio at which the root element's width and height should be in (and I wanted a rectangle). It automatically resizes the inner content too as the Plasma Panel is resized.

How to scroll with arrow keys in a Kirigami ScrollablePage?

The Qt QML based mobile/desktop convergent UI framework Kirigami provides a QML type ScrollablePage to support scrolling through content. Placing any visual QML item into it automatically makes it scrollable if it's larger than the ScrollablePage itself:
ScrollablePage is a Page that holds scrollable content, such as ListViews.
Scrolling and scrolling indicators will be automatically managed.
Kirigami.ScrollablePage {
id: root
//The rectangle will automatically be scrollable
Rectangle {
width: root.width
height: 99999
}
}
(source)
This provides scrollbars and allows scrolling with the mouse wheel, two-finger-scrolling with the touchpad and flicking ("click and throw") scrolling as we're used to from touchscreen devices.
However, it does not allow scrolling with any keyboard keys (Arrow Up / Down, Page Up / Down). How can I make that possible? The usual approach of doing Keys.onUpPressed: scrollBar.decrease() does not work because the ScrollablePage's scrollbar is not accessible as part of its public API.
Instructions
Use a Flickable to wrap the content items you put into your ScrollablePage. Then evaluate key press events in the Flickable and in response execute flick() to scroll the view. Example (combining examples from the Kirigami manual and from the Qt manual):
Kirigami.ScrollablePage {
id: root
Flickable {
focus: true
topMargin: 20; leftMargin: 20; bottomMargin: 20; rightMargin: 20
Keys.onUpPressed: flick(0, 800)
Keys.onDownPressed: flick(0, -800)
Rectangle {
width: root.width
height: 5000
}
}
}
Details and Explanation
While you can't access the scrollbar, you can access what the scrollbar uses to move the view: a Flickable instance. You just have to wrap it around the page's content. If you don't, ScrollablePage internally uses ScrollView to wrap your page's content in a Flickable anyway, but then you don't have a reference on it to execute flick().
Executing flick() does the same as when the user flicks the element, so the scrollbar position etc. will be updated alright.
If it still does not work, then (1) maybe you give too small pixel/second values to Flickable::flick() for scrolling to be visible or (2) maybe the initial Flickable::flickDeceleration values on your platform are messed up. These values are platform specific, so it can require some experimentation. On some platforms, setting them to zero during a flick() will help, while under Linux this is exactly the value preventing any scroll movement.
It is not necessary to enable ScrollablePage::keyboardNavigationEnabled for the above solution to work, since that is only for moving the currentItem of suitable content with the arrow keys (see below), and not for scrolling in general. It will even prevent ordinary scrolling in case your page content is an item view (ListView, GridView etc.).
Alternative solution for item views
If the content of your ScrollablePage is an item view (any QML object that has a currentItem property, such as ListView or GridView), then instead of wrapping that content in a Flickable just enable ScrollablePage::keyboardNavigationEnabled. It will allow you to move the currentItem with the Arrow Up and Arrow Down keys. That's what one usually wants for these views, even though it's not scrolling but rather keyboard navigation.

How do I create a QtWidgets ListView equivalent in Qt Quick Controls?

This question is a little specific, but I've been unable to find someone with the same problem or a clean solution to the problem.
I'm creating a Qt Quick program, and I want to use a QListView as it appears in QtWidgets. This QtWidgets program has three such views, with checkable items (which is optional: not all QListViews have checkable items).
Because Qt Quick Components doesn't appear to have a QListView equivalent, I set out to make my own from existing components. And the result is ... meh. It looks like this and doesn't exactly behave in the same fashion. Clicking on the text/whitespace of an item checks the item, instead of highlighting it. And the border is just ugly, and doesn't appear in GTK-themed environments. It also doesn't obey custom desktop themes, because the background of the items will always be white.
The code for this custom component is fairly brief, and looks like this:
import QtQuick 2.4
import QtQuick.Controls 1.3
// GroupBox creates a border... most of the time. Not in GTK envs
GroupBox {
id: root
property var model: null
// This wraps the ListView up with a scrollbar
ScrollView {
anchors.fill: parent
ListView { // This is the view component
anchors.fill: parent
model: root.model
// This is the white box that the CheckBox is drawn on
delegate: Rectangle {
width: parent.width
height: box.height
// This is the actual item
CheckBox {
id: box
anchors.fill: parent
text: thing // `thing` is just a placeholder value from the model
}
}
}
}
}
Use a QApplication instead of a QGuiApplication. It will require you to add widgets support (and ship Qt widgets libs). This way, Qt Quick Components will automatically get access to much more system theming like background color in text selection.
Additionally, SystemPalette will provide you with a bunch of native colors that you can use if you want.
Unsatisfying system integration using QGuiApplication:
Nice integration using QApplication:

How to add scroll bar for an item that is larger than the screen resolution in qml?

I use QtQuick 1.1 and I have an item like this below:
Item {
id: myItem
width: 12345
height: 12345
//...
}
When I run my qml project, it doesn't show any scroll bar for this item (horizental and vertical).
How can i add scroll bar to it? And if I use Qt and QML together (using a QWidget and QDeclarativeView on it), then what's the solution?
Making UI using qml is kind of UI paradigm shift when compared to making desktop widgets. What you are expecting is a normal desktop widget behavior, which is absent in the most mobile platforms UIs. In them, usually, scroll bars are associated with the lists and not with complete pages.
You can however implement that in qml as well. You can have the top element as flickable instead of a rectangle, and the show the scroll bars yourself based on flicks on the page. Try to go through the qml RSSfeed example to understand how you can use combination of flickable and other elements to achieve this.
P.S. : Also, see the qml desktop components introduced in Qt5. They will give you the widget behavior. See if it fits what you want.
But again, you should ask yourself, what exactly are you trying to achieve here ?

Resources