I want to increase the number when I press any key on the keyboard on QML, it works by making the arrow keys, Keys.onUpPressed: {increment()}
but when I want to increase it by pressing the x key, When I try this command Keys.onXPressed: {increment()} it does not happen. and I want it to increase in proportion to the time the key is pressed, how can I control it.
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
id: root
visible: true;
color: "lightgrey"
width: 500
height: 500
Keys.onPressed: {
switch (event.key) {
case Qt.Key_Up:
vueGrille.commencer();
root.showgrille();
break;
case Qt.Key_Down:
vueGrille.mouveBas();
root.showgrille();
break;
case Qt.Key_Left:
vueGrille.mouveGauche();
root.showgrille()
break;
case Qt.Key_Right:
vueGrille.mouveDroite();
root.showgrille()
break;
default:
break;
}
}
Text {
id: label1
font.pixelSize: 30
property int upPressed: 0
text: "Key UP Pressed " + upPressed + "Times"
onTextChanged: console.log("Text Changed to " +text)
focus: true
Keys.onUpPressed: {
increment()
}
Keys.onEscapePressed: {
label1.text = ''
}
function increment(){
upPressed = upPressed + 1
}
}
}
There is no Keys.onXPressed handler. You need to check the key in Keys.onPressed.
Keys.onPressed: {
if (event.key === Qt.Key_X) {
increment()
}
}
Related
I'm working on an app which is supposed to display a camera stream from a webcam. It's a single-page app which only shows a Video QML element showing the stream (which currently is a simple .avi file) and a Label element indicating the current connection state from an MQTT connection.
Here's the code:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.1
import QtMultimedia 5.12
import MqttClient 1.0
Window {
width: 360
height: 640
visible: true
title: qsTr("Doorbell")
MqttClient {
id: client
// TODO
property string _host: "localhost"
property string _port: "1883"
property string _topic: "my/topic"
hostname: _host
port: _port
Component.onCompleted: {
connectToHost()
}
onConnected: {
subscribe(_topic)
}
onMessageReceived: {
video.play()
}
Component.onDestruction: {
disconnectFromHost()
}
}
GridLayout {
anchors.fill: parent
anchors.margins: 10
columns: 2
Video {
id: video
objectName: "vplayer"
width: parent.width
height: 300
Layout.columnSpan: 2
autoPlay: false
source: "file:///path/to/my/test.avi"
onErrorChanged: {
console.log("error: " + video.errorString)
}
MouseArea {
anchors.fill: parent
onClicked: {
video.muted = !video.muted
}
}
focus: true
Image {
id: muteIndicator
source: "mute_white.png"
width: 64
height: width
visible: video.muted
anchors.centerIn: parent
}
}
Label {
function stateToString(value) {
if (value === 0)
return "Disconnected"
else if (value === 1)
return "Connecting"
else if (value === 2)
return "Connected"
else
return "Unknown"
}
Layout.columnSpan: 2
Layout.fillWidth: true
text: stateToString(client.state) + "(" + client.state + ")"
}
}
}
Here's a screenshot:
Here's the clue:
I tried removing the Label and replacing it with a simple rectangle indicator (red or green) to show if the connection is currently active.
However, when replacing the text content of the Label element, the Video element completely disappears.
What I've tried:
removing the stateToString(client.state) + "(" + client.state + ")" part and replacing it with text: "Connected(2)"
replacing stateToString(... with an empty string (text: "")
replacing the content of stateToString(...) with return "Connected(2)"
and a lot of different more seemingly completely useless things
Example code:
// ...
Label {
function stateToString(value) {
if (value === 0)
return "Disconnected"
else if (value === 1)
return "Connecting"
else if (value === 2)
return "Connected"
else
return "Unknown"
}
Layout.columnSpan: 2
Layout.fillWidth: true
text: "Connected(2)"
// enabled: client.state === MqttClient.Connected
}
// ...
Unless I set text to the exact value stateToString(client.state) + "(" + client.state + ")" or at least stateToString(client.state), the Video element will always disappear in the QML view:
I have no idea of what might be the reason for this.
Any help is greatly appreciated, thanks.
Try adding:
Layout.fillWidth: true
after:
objectName: "vplayer"
I'm 99% sure the root of the problem is in the way you have used the layouts. In another word, you have not placed your QML elements in a robust way. since QML has so much flexibility in positioning elements in UI, it matters in QML to put your elements in a well-defined, robust way.
I trying to understand how bindings works when dynamic objects are used. And don't understand anything.
In code bellow I have "static" bindings:
property bool flag1: cfg_flag1
and create dynamic binding that set flag1 to true,
then I destroy binding and make sure that it really destroyed (via logs),
after that I trigger initial binding, but looks like binding restoring doesn't work, it prints:
qmlscene /tmp/Test.qml
qml: set flag1 to true
qml: buggon1 cliecked
qml: end of clicked
qml: destroyed
qml: timer trigger
So restoreMode: Binding.RestoreBinding doesn't restore previous binding or I missed something?
import QtQuick 2.0
import QtQuick.Controls 2.15
Rectangle {
id: rect
width: 100
height: 100
color: "red"
property bool flag1: {
console.log("set flag1 to", cfg_flag1);
return cfg_flag1;
}
property bool cfg_flag1: true
Text {
anchors.centerIn: parent
text: "flag1: " + flag1.toString() + ", cfg_flag1 " + cfg_flag1.toString()
}
Timer {
id: timer
interval: 1000
repeat: false
onTriggered: {
console.log("timer trigger");
cfg_flag1 = false;
}
}
Button {
anchors.top: parent.top
text: "button 1"
onClicked: {
console.log("buggon1 cliecked");
let temp = cmpBinding.createObject(rect, {
"target": rect,
"property": "flag1",
"value": true,
"restoreMode": Binding.RestoreBinding,
});
temp.Component.onDestruction.connect(function() { console.log("destroyed"); });
temp.destroy();
console.log("end of clicked");
timer.start();
}
}
Component {
id: cmpBinding
Binding {
}
}
}
Your code is OK. This is just another bug of Binding =/.
To make it work, you can add
"when": true to list of properties for temp
temp.when = false; on temp's destruction
Here is your edited code
import QtQuick 2.0
import QtQuick.Controls 2.15
Rectangle {
id: rect
width: 100
height: 100
color: "red"
property bool flag1: {
console.log("set flag1 to", cfg_flag1);
return cfg_flag1;
}
property bool cfg_flag1: true
Text {
anchors.centerIn: parent
text: "flag1: " + flag1.toString() + ", cfg_flag1 " + cfg_flag1.toString()
}
Timer {
id: timer
interval: 1000
repeat: false
onTriggered: {
console.log("timer trigger");
cfg_flag1 = false;
}
}
Button {
anchors.top: parent.top
text: "button 1"
onClicked: {
console.log("buggon1 cliecked");
let temp = cmpBinding.createObject(rect, {
"target": rect,
"property": "flag1",
"value": true,
"restoreMode": Binding.RestoreBinding,
"when": true
});
temp.Component.onDestruction.connect(function() { temp.when = false; console.log("destroyed"); });
temp.destroy();
console.log("end of clicked");
timer.start();
}
}
Component {
id: cmpBinding
Binding {
}
}
}
I'd like to check whether or not the mouse and the spacebar keys are being pressed at the same time using QML
I can check if the mouse and other modifier keys are being pressed. For instance:
MouseArea {
onPressed: {
if(mouse.modifiers & QT.ControlModifier) {
// do something
}
}
}
However, the only way I know how to check for keys is inside of the Keys.onPressed handlers. Is there a way to communicate between the MouseArea onPressed and Keys.onPressed in unison?
Here is example code of the same issue:
MyItem.qml
import QtQuick 2.12
Rectangle {
id: element
width: 100
height: 100
color: "orange"
signal mySignal()
property int myState: MyItem.Bits.None
enum Bits {
None = 0,
MouseOn = 1,
KeyOn = 2,
AllOn = 3
}
function checkBits()
{
if(element.myState === MyItem.Bits.AllOn)
{
element.mySignal();
element.myState = MyItem.Bits.None;
}
}
MouseArea {
anchors.fill: parent
onPressed: {
element.myState |= MyItem.Bits.MouseOn;
element.checkBits();
}
onReleased: {
element.myState &= ~MyItem.Bits.MouseOn;
element.checkBits();
}
}
Keys.onSpacePressed: {
element.myState |= MyItem.Bits.KeyOn;
element.checkBits();
}
Keys.onReleased: {
if(element.myState & MyItem.Bits.KeyOn)
{
element.myState &= ~MyItem.Bits.KeyOn;
element.checkBits();
}
}
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 600
height: 400
MyItem {
anchors.centerIn: parent
focus: true
onMySignal: {
console.log("My Signal")
}
}
}
MySignal will be fired on simultaneously Mouse and Space clicking.
Note, enum requires Qt 5.10 or higher
When using Keys as a attached property of qml, but Keys.onReleased was executed when there was no key released event! how solve it?
import QtQuick 2.4
Item {
property string imagePath
property string btnText
property string btnColor: "white"
property double btnWidth: 0
property double btnHeight: 0
property double btnRadius: 0
property double btnTextSize: 0
property double btnOpcity: 0.9
property bool btnEnable: true
property int spaceKeyEventTimes:0
id: umButton
width: 100
height: 100
Rectangle{
id: umButton_Rec
width: btnWidth
height: btnHeight
color: btnColor
radius: btnRadius
opacity: btnOpcity
focus: true
Text{
//focus: true
style: Text.Raised
text: btnText
font.pixelSize: 29
}
}
//////////////Handle KeyEvent from the system//////////////////
Keys.enabled: true;
Keys.onPressed: {
switch(event.key)
{
case Qt.Key_Space:
console.log( "emit btnPressed()" )
event.accepted = true
break;
default:
break;
}
}
Keys.onReleased: {
switch(event.key)
{
case Qt.Key_Space://Qt.Key_Space
console.log("emit btnReleased()")
event.accepted = true
break;
default:
break;
}
}
}
I have to create a list of toggle buttons and they've got to react to pressing keystroke Alt + NUMBER_OF_BUTTON independently of each other.
Code of this button looks like this:
import QtQuick 2.0
Rectangle {
property bool opened: false
property int number: 0
width: 40
height: 20
color: (opened) ? "orange" : "grey"
border.width: 1
focus: true
Text {
anchors.centerIn: parent
text: "Кл. " + number
font.pixelSize: parent.width * 0.3
}
Keys.onPressed: {
if (number <= 9 && number >= 0 &&
event.key == (Qt.Key_0 + number) && (event.modifiers & Qt.AltModifier))
{
opened = (opened) ? false : true;
event.accepted = true;
}
}
}
However when I try to use these buttons, only the first button in a column reacts to its keystroke.
Column {
Button {
focus: true
number: 1
}
Button {
focus: true
number: 2
}
....
}
Could you please explain me what's wrong with it?