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)
}
}
}
}
Related
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.
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
}
}
}
I have a combobox in qml in a as a TableViewColummn and I define it as follows:
import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
ListModel {
id: comboModel
ListElement {
text: ""
Index: -1
Dims: -1
}
}
TableViewColumn {
id: imageTypeList
role: "ImageType"
title: "Image Type"
width: 100
delegate: Rectangle {
ComboBox {
anchors.verticalCenter: parent.verticalCenter
anchors.margins: 2
model: comboModel
onActivated : {
console.log(comboModel.get(index).Index)
}
}
}
}
My question is that if it is possible to disable a combobox menu item given a index to the item in the ComboBox. So, I would not like to change the underlying model but actually simply disable the item and not allow the user to select it.
Is it possible to disable a ComboBox menu item ... and not allow the user to select it?
Sure, it is possible.
To do it using Quick Controls 2 you need to create ComboBox delegate this way:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
Window {
visible: true
width: 640
height: 200
title: qsTr("Let's disable some items in ComboBox")
ComboBox {
id: control
currentIndex: 0
anchors.centerIn: parent
model: [
{ text: "Enabled item.", enabled: true },
{ text: "Supposed to be disabled. Can't click on it.", enabled: false},
{ text: "Last, but enabled item.", enabled: true}
]
width: 500
textRole: "text"
delegate: ItemDelegate {
width: control.width
text: modelData.text
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
highlighted: ListView.isCurrentItem
enabled: modelData.enabled
}
}
}
If you are using Quick Controls 1, you should provide your own implementation of ComboBox component.
I'd like to arrange for a specific control to get the focus within a TabView Tab. Its seems that the first one gets the focus regardless of what I do. I have tried setting focus:false everywhere else but it doesn't work.
Consider the following code. I have a simple column containing two RadioButtons and a TextField. I'd like to arrange for the TextField to always get focus when the tab is selected, but it always goes to the first RadioButton
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3
ApplicationWindow
{
visible: true
width: 800
height: 400
TabView
{
anchors.fill: parent
Tab { title: "tab1"; sourceComponent: foo }
Tab { title: "tab2"; sourceComponent: foo }
}
Component
{
id: foo
ColumnLayout
{
spacing: 32
ExclusiveGroup { id: optionGroup }
RadioButton
{
// i always get the focus!!
exclusiveGroup: optionGroup
text: "Click me"
activeFocusOnPress: true
focus: false
}
RadioButton
{
exclusiveGroup: optionGroup
text: "No, click me!"
activeFocusOnPress: true
focus: false
}
TextField
{
// but i want the focus
placeholderText: "type here"
focus: true
}
}
}
}
Press "tab2" to see this,
I tried forcing within TabView by adding,
onCurrentIndexChanged: getTab(currentIndex).item.forceActiveFocus()
But it makes no difference.
I've read the explanation of focus but it hasn't helped in this case.
Thanks for any suggestion or help,
Probably a bug. Try Qt Quick Controls 2.0 instead:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
width: 800
height: 400
header: TabBar {
id: bar
width: parent.width
TabButton {
text: qsTr("tab1")
}
TabButton {
text: qsTr("tab2")
}
}
StackLayout {
anchors.fill: parent
currentIndex: bar.currentIndex
ColumnLayout {
id: columnLayout
spacing: 32
ButtonGroup {
id: optionGroup
buttons: columnLayout.children
}
RadioButton {
text: "Click me"
}
RadioButton {
text: "No, click me!"
}
TextField {
placeholderText: "type here"
focus: true
}
}
}
}
In QML, I have a Tab containing a TextField and a Button. How do I ensure the Button has focus when the tab is selected, instead of the TextField? Setting "focus:" to true and false, respectively, does not do it. In the code below, the goal is for btnRefresh to have focus when a tab is selected, instead of txtName.
main.qml:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.2 // For TabViewStyle
ApplicationWindow {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
TabView {
id: tabView
anchors.fill: parent
anchors.margins: 20
tabPosition: Qt.BottomEdge
Tab {title: "Tab 1"; source: "mytab.qml"}
Tab {title: "Tab 2"; source: "mytab.qml"}
style: TabViewStyle {
frameOverlap: 1
tab: Rectangle {
color: styleData.selected ? "steelblue" :"lightsteelblue"
border.color: "steelblue"
implicitWidth: Math.max(text.width + 4, 80)
implicitHeight: 20
radius: 2
Text {
id: text
anchors.centerIn: parent
text: styleData.title
color: styleData.selected ? "white" : "black"
}
}
frame: Rectangle { color: "steelblue" }
}
}
}
mytab.qml:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
Rectangle {
anchors.fill: parent
GridLayout {
columns: 2
anchors.fill: parent
rowSpacing: 10
RowLayout {
Layout.columnSpan: 2
Label {
id: lblName
text: "Name:"
}
TextField {
id: txtName;
text: "a name"
Layout.preferredWidth: lblName.implicitWidth * 1.5;
focus: false
}
}
TextArea {
id: textSetup
text: "Text Area"
Layout.columnSpan: 2
Layout.fillWidth: true
Layout.fillHeight: true
}
Button {
id: btnRefresh
Layout.columnSpan: 2
Layout.alignment: Qt.AlignHCenter
text: qsTr("Refresh")
focus: true
}
}
}
Whenever you switch tabs in a TabView, a signal handler onVisibleChanged is called on the two tabs (one that disappeared and the one that appeared) since the visibility of these tabs has changed. You can try adding following code to your Tabs:
Tab {
id: tab1
title: "Tab 1"; source: "mytab.qml"
onVisibleChanged: {
if (visible) tab1.item.funcSetFocusOnButton();
}
}
Please note the way a function is called on a tab using item.
Now in "mytab.qml", you create a javascript function funcSetFocusOnButton which sets focus on your button. So your mytab.qml will have this additional code:
Rectangle {
//Your GridLayout{}
funcSetFocusOnButton() {
btnRefresh.forceActiveFocus();
}
}
Note here that the function funcSetFocusOnButton should be a direct child of your base item (rectangle here). Hope this helps!