QML Button assign arrow shortcut - qt

Is it possible to assign an arrow shortcut to a QML Button? With the Action item I can assign a shortcut by string or by KeySequence (https://doc.qt.io/qt-6/qml-qtquick-controls2-action.html#shortcut-prop), but how can I assign a shortcut of an arrow?

you can use Shortcut ,like this :
import QtQuick
import QtQuick.Controls 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Shortcut")
Button {
id: button
x: 199
y: 144
width: 190
height: 105
text: qsTr("Button")
Shortcut
{
sequence:"Up" // "Down" , "Right" ,"Left"
onActivated:button.clicked()
}
onClicked:
{
console.log("Up Arrow")
}
}
}
"Up" ↑, "Down" ↓, "Right"→ ,"Left"← used for Arrows in keyboard.

Related

QML Hold Image Button to continuously increment value

I am trying to have a display value continuously increment by 1 while a button is pressed and held down. I implemented my button with an Image element which is using a MouseArea to increment the display value when pressed once. I am not sure if there is another default signal that supports it, and if there is, I can't find one.
I am using Python+Pyside6, but would hope this is something I can accomplish with just QML.
Image{
id: incrementValue
source: "icons/arrow-up-circle-sharp.svg"
fillMode: Image.PreserveAspectFit
property int size: 50
sourceSize.width: size
sourceSize.height: size
smooth: true
Layout.alignment: Qt.AlignTop
visible: true
MouseArea {
anchors.fill: parent
onClicked: {
displayValue.text = (( displayValue.text*1.00) + 1.0).toLocaleString(Qt.locale("f"))
}
}
}
Text{
id: displayValue
text: "00.00"
}
I write this Example For you :
If you want set Image for Button Put Image inside it.
import QtQuick 2.12
import QtQuick.Window 2.12
import Qt.labs.qmlmodels 1.0
import QtQuick.Controls 2.13
Window {
visible: true
width: 400
height: 400
title: qsTr("Hello World")
property int counter: 0
Button {
id: button
x: 45
y: 46
text: qsTr("up")
onClicked:
{
counter +=1
}
}
Button {
id: button1
x: 188
y: 46
text: qsTr("down")
onClicked:
{
counter -=1
}
}
Text {
id: name
x: 118
y: 130
width: 98
height: 60
text: counter
}
}
As I understand from your question :
There is PressAndHold Signal in Button use onPressAndHold instead of onClicked.
Use a Timer with a 1s interval. Bind it’s running property to the pressed property of a MouseArea or Button. On timeout, increase respectively decrease the value.

How to set objectName for PopupItem from QML?

QML Popup and derived controls are creating a PopupItem object which is a visual representation of it, but Popup itself is parented to the contentData of the application window. objectName specified for Popup is not applied to PopupItem. For example, the following application:
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Popup Test")
Button {
text: "Open"
onClicked: dummyPopup.open()
}
Popup {
id: dummyPopup
objectName: "dummyPopup"
x: 100
y: 100
width: 200
height: 300
modal: true
focus: true
}
}
creates PopupItem with empty objectName
Is there a way to set objectName for PopupItem from QML?
Set the objectName of its contentItem upon completion:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Popup Test")
Button {
text: "Open"
onClicked: dummyPopup.open()
}
Popup {
id: dummyPopup
objectName: "dummyPopup"
x: 100
y: 100
width: 200
height: 300
modal: true
focus: true
Component.onCompleted: {
contentItem.objectName = "foo"
print(contentItem)
}
}
}
By the way, if this is for auto tests, I have a hack in C++ that avoids the need to give an objectName to the contentItem:
QObject *TestHelper::findPopupFromTypeName(const QString &typeName) const
{
QObject *popup = nullptr;
foreach (QQuickItem *child, overlay->childItems()) {
if (QString::fromLatin1(child->metaObject()->className()) == "QQuickPopupItem") {
if (QString::fromLatin1(child->parent()->metaObject()->className()).contains(typeName)) {
popup = child->parent();
break;
}
}
}
return popup;
}
You can then use that function like this in your test:
const QObject *newProjectPopup = findPopupFromTypeName("NewProjectPopup");
QVERIFY(newProjectPopup);
QTRY_VERIFY(newProjectPopup->property("opened").toBool());

How should I start QML files?

I have 4 QML files: MainMenu.qml, AppArea.qml, Result.qml and main.qml.
When my app starts, I want to see first page as MainMenu.qml fullscreen. There is a button (on MainMenu.qml) to start AppArea.qml. When I click the the button, I want to start AppArea.qml as fullscreen new window.
There is a button (on AppArea.qml), when I click that button, I want to show Result.qml but I want to see Result.qml on AppArea.qml, I mean when Result.qml come outs, AppArea.qml will not disappear but Result.qml will appear on AppArea.qml.
There is a button on Result.qml. When I click the button, the Repeater in AppArea.qml will regenerate, because maybe model of Repeater changing like 1, 2, 3, 4.... There is a button on AppArea.qml, when I click the button, I want to open MainMenu.qml as a fullscreen new window like AppArea.qml.
Actually you can think basic: My app is a game like this:
How way should I choose for these jobs?
In addition to the mentioned post, in your case you are using the component from qml file, so you need to load the component first, your main.qml can be like this:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
id: mainWindow
title: "Main window"
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id: mainMenuLoader
}
Component.onCompleted: {
mainMenuLoader.source="mainMenu.qml"
var mainMenu = mainMenuLoader.item.createObject(mainWindow);
mainWindow.hide()
}
}
and your mainMenu.qml can look like this:
import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Controls 2.2
Component {
id: mainMenu
Window {
id:mmenu
title: "Main Menu"
width: 600
height: 600
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id: appAreaLoader
}
Text {
text: "This is mainMenu"
}
Button{
id: loadAppArea
anchors.centerIn: parent
text: "Start Game"
onClicked: {
appAreaLoader.source="appArea.qml"
var appArea = appAreaLoader.item.createObject(mainMenu);
hide()
}
}
}
}
you will need to do the same for successive windows ...etc.
While for result, you need to use a MouseArea:
appArea.qml:
Component {
id: appMenu
Window {
id:appMenuWindow
title: "App Menu"
width: 600
height: 600
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id:anotherLoader
visible: true
anchors.left: appMenuText.left
anchors.top: appMenuText.bottom
width: parent.width/3
height: parent.height/3
}
Text {
id: appMenuText
text: "This is App Area"
anchors.centerIn: parent
}
Button{
id: loadResult
text: "Show Result"
onClicked: {
anotherLoader.source = "result.qml"
anotherLoader.visible=true
}
}
Button{
anchors.right: parent.right
id: loadMainMenu
text: "Open main Menu"
onClicked: {
hide()
//mmenu.show()
anotherLoader.setSource("main.qml")
}
}
}
}
result.qml:
Rectangle{
color: "green"
Text {
anchors.centerIn: parent
id: resultxt
text: qsTr("This is result, Click to close")
}
MouseArea {
anchors.fill: parent
onClicked: { anotherLoader.visible = false
}
}
}

Creating a horizontal Tumbler or circular SwipeView in QML

I'd like to replace a SwipeView with an Tumbler in QML as I prefer the notion, that there is no first and no last Item.
The problem is, I can't find any other way to get this Tumbler tumble horizontally instead of vertically, but to rotate it by -90° and then rotate the Items back by +90°
This is my code so far, and works as expected:
import QtQuick 2.5
import QtQuick.Controls 2.0
import QtQuick.Window 2.2
Window {
id: root
visible: true
width: 640
height: 480
Row {
id: buttons
spacing: 2
Button {
text: '0'
onClicked: tumbl.currentIndex = 0
}
Button {
text: '1'
onClicked: tumbl.currentIndex = 1
}
Button {
text: '2'
onClicked: tumbl.currentIndex = 2
}
Button {
text: '3'
onClicked: tumbl.currentIndex = 3
}
}
Tumbler {
id: tumbl
rotation: -90 // <---- Rotate there
anchors {
top: buttons.bottom
left: buttons.left
right: buttons.right
bottom: parent.bottom
}
model: 4
delegate: Rectangle {
rotation: 90 // <---- Rotate back
color: 'red'
border.width: 15
Text {
anchors.centerIn: parent
text: index
}
}
visibleItemCount: 1
Component.onCompleted: contentItem.interactive = false
}
}
You can see the two lines, in which I do the rotation marked with a comment.
Does anybody know a way to either produce this circular behavior with a SwipeView or to change the tumble-orientation of the tumbler without this rotation trick?

Error when several Actions with the same Shortcut

I have a TabView. Each Tab is in the separate file (here for simplicity I composed all the code in one file). I'd like to launch some function using Enter key or a Button. All is ok when I click the Buttons. But when I press Enter, nothing happens (onTriggered event handler is never executed) and I also get an error:
QQuickAction::event: Ambiguous shortcut overload: Return
If I have only one Tab the problem does not occur and the onTriggered handler is correctly executed.
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.1
Item {
width: 640
height: 480
TabView {
id: tabView
currentIndex: 0
anchors.fill: parent
Layout.minimumWidth: 360
Layout.minimumHeight: 360
Layout.preferredWidth: 480
Layout.preferredHeight: 640
Tab {
id: tab1
active: true
title: "One"
Item {
id: item
x: 16
y: 8
width: 640
height: 480
Action {
id: calcDataAction
text: "Run"
shortcut: StandardKey.InsertParagraphSeparator
tooltip: "one"
onTriggered: {
console.log("one")
}
}
Button {
action: calcDataAction
id: calcButton
x: 20
y: 20
height: 40
width: 100
}
}
}
Tab {
id: tab2
active: true
title: "Two"
Item {
id: item2
x: 16
y: 8
width: 640
height: 480
Action {
id: calcDataAction2
text: "Run"
shortcut: StandardKey.InsertParagraphSeparator
tooltip: "two"
onTriggered: {
console.log("two")
}
}
Button {
action: calcDataAction2
id: calcButton2
x: 20
y: 20
height: 40
width: 100
}
}
}
}
}
How can I solve it?
As a workaround I could use the following shortcut binding in the Action :
shortcut: tab1.activeFocus ? StandardKey.InsertParagraphSeparator : ""
But the problem is that, first I need (don't know why) to click on all tabs' headers, before events could trigger...
Action has a property enabled, like almost all visual and non-visual types in QML. If enabled - by default it is - an Action can be triggered.
Having all the Actions active at the same time does not make sense since only a single Tab can be visible. Hence, an approach to solve the issue would be to just enable one Action at a time, the one associated to the currently visible tab, that is:
enabled: <tab_id>.visible
Following your code, a minimal example looks like this:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
ApplicationWindow {
width: 300
height: 200
visible: true
TabView {
id: tabView
anchors.fill: parent
Tab {
id: tab1
title: "One"
Action {
id: calcDataAction
enabled: tab1.visible
shortcut: "Ctrl+O"
onTriggered: console.log(tab1.title)
}
}
Tab {
id: tab2
title: "Two"
Action {
id: calcDataAction2
enabled: tab2.visible
shortcut: "Ctrl+O"
onTriggered: console.log(tab2.title)
}
}
}
}

Resources