How to make tab order navigation in QML
For example I have such code:
TextInput { id: one }
TextInput { id: two }
TextInput { id: three }
And I need on pressing tab from focus on "one" move to "three", haven't found that in official documentation.
TextInput {
id: one
KeyNavigation.tab: three
}
Key navigation in QML is documented at this page and provide some example at:
http://qt-project.org/doc/qt-4.8/qml-keynavigation.html
Related
Using Qt Quick Controls 2, you can create a "traditional" menu bar like this:
ApplicationWindow {
id: window
width: 320
height: 260
visible: true
menuBar: MenuBar {
Menu {
title: qsTr("&File")
Action { text: qsTr("&New...") }
Action { text: qsTr("&Open...") }
Action { text: qsTr("&Save") }
Action { text: qsTr("Save &As...") }
MenuSeparator { }
Action { text: qsTr("&Quit") }
}
Menu {
title: qsTr("&Edit")
Action { text: qsTr("Cu&t") }
Action { text: qsTr("&Copy") }
Action { text: qsTr("&Paste") }
}
Menu {
title: qsTr("&Help")
Action { text: qsTr("&About") }
}
}
}
This works ok, but when the user presses on a menu and then drag the mouse while pressed, on the menus are not hovered. In order to hover over the menus, the mouse cannot be in a pressed state (using Qt Widgets https://doc.qt.io/qt-5/qtwidgets-mainwindows-menus-example.html this is not needed).
Is there a way to make the MenuBar, hover over items while the mouse is pressed?
When you did through this doc
https://doc.qt.io/qt-5/qml-qtquick-controls2-action.html
You then go to this doc and have high hopes when reading about "hoverEnabled"
https://doc.qt.io/qt-5/qml-qtquick-controls2-toolbutton-members.html
You really need these two signals entered() exited() from a MouseArea.
https://doc.qt.io/qt-5/qml-qtquick-mousearea.html
The short hopeful hack is to see if the documentation is "just wrong" and somewhere deep in the class structure they declared a MouseArea for a button and you really do get entered() and exited().
How else would you be able to implement hoverEnabled()? The "widget" has to know the mouse entered and did not yet exit. They may well be consuming that, but you should be able to dig through the source and find child entity that you can connect to the signal of.
There is not an easy way.
The underlying issue is that MenuItem is implemented as a Button.
When you press a button and release on another button, none of them register a click.
However, on traditional menus, if you press an item and release on another one, the item that registers the release is triggered.
The public API offered by QtQuick Controls 2 does not seem to offer a way to easily change this. So to get what you want Isee the following solutions:
Use Qt.labs.platform to build your menus, these will be native menus so they should have the correct behavior. However it still in a preview state and i have not tested them.
Reimplement MenuItem. Since it is part of Qt Quick Controls 2 it is easy to reimplement your own MenuItem, see Qt documentation. However, you will have to use MouseArea to catch user inputs and force the behavior you want.
EDIT
The 2nd solution won't work. In Qt once an Item (or a QWidget) accepts a press event, it grabs the mouse until it is released. So reimplementing MenuItem and adding MouseArea to them won't help.
Knowing that it seems that the solution would to reproduce what QMenu is doing: You need to have a single Item responsible for handling mouse events. So you should not let each MenuItem handles mouse events individually. Instead you should handle mouse events at the Menu or MenuBar level, process the events and manually change the MenuItems.
At this point I do not know if it is easier to customize Menu and MenuItem or to jus write your own Menu from scratch.
on qt quick controls 2, how can I configure a button Item with a dropdown menu of others buttons. When the user click on this button is triggered onClicked signal and under the button should be open a dropdown menu with other buttons. I have try with ButtonGroup but I don't know if this is the best practice. There is some Controls2 item to be use? Thanks in advice
Best Regards
Daniele
There is Menu from QtQuick.Controls 2.0 that can do what you want.
Example taken from the documentation :
Button {
id: fileButton
text: "File"
onClicked: menu.open()
Menu {
id: menu
y: fileButton.height
MenuItem {
text: "New..."
}
MenuItem {
text: "Open..."
}
MenuItem {
text: "Save"
}
}
}
I'm trying to implement a keyboard shortcut control for my qml application. I know there's the possibility to do that with an Action element, but I don't want menus and toolbars which are then mandatory to use.
That's why I'm approaching this topic with keyboard events. For this, I need to have the element performing the action to be in focus. But my goal is a global shortcut control, so theoratically I'd need to have all the elements in question in focus.
I found the FocusScope type in the documentation, but I'm not sure if this is what I need.
Does it mean that the focus of nested FocusScopes 'slides' through to the last element that's not a FocusScope and acquiring focus manually with focus: true thus only this last element holding focus? Or do all the elements on the way down the slide that acquire focus have the activeFocus property set?
Is this the right approach or would I need something else?
Focus in Qt Quick is a mess in my opinion. It always confuses me and I end up hacking around it with forceActiveFocus(). I'd recommend the new Shortcut type:
Shortcut {
sequence: StandardKey.Quit
context: Qt.ApplicationShortcut
onActivated: Qt.quit()
}
With the context property, you can choose whether you want the shortcut to apply to the current window or the entire application.
The motivation for this type can be seen in the comments of patch set 5:
Shortcut aims to supersede Action. I want to kill the latter in the future because...
compare the actual user code: http://cutebin.fi/prwznhkbo
look at the amount of "action" related expressions all around BasicButton.qml
IMHO the whole concept doesn't quite fit mobile/embedded or QML
Action was a frequently requested feature. Now that they have it, the frequent questions are "how to use a different icon/text" or "how to know the source that triggered an action". Both are contradicting the sole purpose of Action, and neither "problem" would exist if they just wrote simpler QML code in the first place, as illustrated by the example snippet. :)
Evidently the most usable part of Action is the shortcut feature. Those who need shortcuts are not happy that they need to use Action, because "what's up with all this other stuff, I just want a shortcut".
Maybe there are different ways of achieving this, but the way I know is the following one.
The idea is to have an Item which controls the key events you need to handle.
I'll explain myself with an example. As you will see, if we have input widgets (i.e. TextInput) we have to implement a mechanism to return the input to our Item in order to process again the keyboard events. In this example, the Qt.Key_Escape key will be used to set the focus back.
import QtQuick 2.4
import QtQuick.Controls 1.3
ApplicationWindow {
id: mainwindow
title: qsTr("Hello")
width: 640
height: 480
visible: true
Item {
anchors.fill: parent
focus: true
Keys.onPressed: {
if ( (event.key === Qt.Key_Q) && (event.modifiers & Qt.ShiftModifier) ) {
rect.blue()
} else if ( (event.key === Qt.Key_W) && (event.modifiers & Qt.AltModifier) ) {
rect.red()
} else if ( (event.key === Qt.Key_E) && (event.modifiers & Qt.AltModifier) ) {
text.text = 'Key Alt+E was pressed'
}
}
Rectangle{
id: rect
width: 100
height: 100
color: "black"
function blue() {color = "blue"}
function red() {color = "red"}
}
Text {
id: text
anchors.centerIn: parent
font.pointSize: 20
}
TextInput {
id: textinput
anchors.top: text.bottom
text: "sample text"
Keys.onPressed: {
if (event.key === Qt.Key_Escape) {
console.log('Key Escape was pressed');
parent.focus = true;
}
}
}
}
}
Edit #1: #Mitch suggested to use the Shortcut QML Type. If you can use it (it's available since Qt 5.5), the code will be slightly different. Anyway, you need also to set the focus to the main app in some cases depending on the shortcut sequences implemented. For example, if we're typing text, Shift+Q doesn't have effect in this example. We need to press Escape first.
import QtQuick 2.5
import QtQuick.Controls 1.3
ApplicationWindow {
id: mainwindow
title: qsTr("Hello")
width: 640
height: 480
visible: true
Shortcut {
sequence: "Shift+Q"
onActivated: rect.blue()
context: Qt.ApplicationShortcut
}
Shortcut {
sequence: "Alt+W"
onActivated: rect.red()
context: Qt.ApplicationShortcut
}
Shortcut {
sequence: "Alt+E"
onActivated: text.text = 'Key Alt+E was pressed'
context: Qt.ApplicationShortcut
}
Item {
anchors.fill: parent
Rectangle{
id: rect
width: 100
height: 100
color: "black"
function blue() {color = "blue"}
function red() {color = "red"}
}
Text {
id: text
anchors.centerIn: parent
font.pointSize: 20
}
TextInput {
id: textinput
anchors.top: text.bottom
text: "sample text"
Keys.onPressed: {
if (event.key === Qt.Key_Escape) {
console.log('Key Escape was pressed');
parent.focus = true;
}
}
}
}
}
Much like Mitch, I found focus to be a mess in QML, much like many other aspects of it.
I ended up implementing my own "active focus / selection" scheme. Basically I keep a list of item pointers as my "active selection", I have the keyboard focus fixed at a single item acting as an event dispatcher, and it redirects keyboard events to all items in the active selection list. I still use QML's MouseArea to manage the selected items.
I would like to customize style of my application and I'm stuck on the style of TextField pop-up menu.
TextField.style allows to customize the look of TextField but it doesn't contain the style of the menu. According to documentation there is a property menu containing the Menu so I tried something like this:
TextField {
menu.style: MenuStyle {
//...
}
}
Code above complains that property style is non-existent so it's not exactly Menu, it's Component used to create the menu and I don't know if there is a way to get through it to the actual Menu. Documentation only mentions that TextField.menu can be set to null to disable it completely and doesn't provide other use cases.
So is there a way to get to the menu of TextField and change its style?
Well, you should post all relevant code here. Anyway, you cannot define the TextField menu and its style separately. See the example below to customize Menu style and adding it to the TextField inline:
TextField {
text: "text here"
anchors.centerIn: parent
menu: Menu {
style: MenuStyle {
frame: Rectangle {
color: "green"
border.color: "purple"
}
itemDelegate {
background: Rectangle {
color: "yellow"
}
label: Text {
color: styleData.selected ? "red" : "blue"
text: styleData.text
}
}
}
MenuItem { text: "Cut" }
MenuItem { text: "Copy" }
}
}
See this page for complete list of MenuStyle properties.
I'm writing a test application to try out what QML has to offer. I have created a simple button and tried to create a tooltip on mouse hover event. I found several solutions already how to make that happen (example) and it is not a problem.
In the documentation, however, I have encountered a button property called tooltip. Now I assumed if a built-in component has such a property then creation of tooltip is automated. Apparently that is not the case, since defining tooltip property did not change anything.
The question is what is this property actually used for?
Button {
id: myButton
x: 10
y: 10
text: "Click me"
tooltip: "Some tooltip"
}
Showing of tooltip requires receiving of mouse hover events and this is possible only if your button is not overlapped with some another MouseArea with hoverEnabled property equal to true. Following example shows tooltip fine on OS X and Qt 5.2.1:
import QtQuick 2.0
import QtQuick.Controls 1.1
Rectangle {
width: 360
height: 360
Text {
anchors.centerIn: parent
text: "Hello World"
}
Button {
id: myButton
x: 10
y: 10
text: "Click me"
tooltip: "Some tooltip"
}
}