I want to do something when click or doubleclick in the scene3d. But nothing to show in my console
Scene3D {
aspects: ["logic", "input"]
...
MouseDevice { id: mouse_device }
MouseHandler {
sourceDevice: mouse_device
onPressed: { ... }
onPositionChanged: { ... }
onWheel: { ... }
onClicked: { console.log("click") } // failed
onDoubleClicked: { ... } // failed
}
...
}
Maybe I am missing something? Or is there another way to do it?
Related
TankModel { id: _model }
Connections {
target: _model
onModelUpdated: {
_tankList.enabled = true;
}
}
StackView {
id: _stack
anchors.fill: parent
initialItem: _page1
}
Component {
id: _page1
ComboBox {
id: _tankList
model: _model
}
}
After running the program, I get the error:
ReferenceError: _tankList is not defined
The error points to line number 6.
How to make ComboBox visible to Connections?
How to solve this problem?
You can instanciate your model inline. In this case the model can access its parent.
...
ComboBox {
id: _tankList
model: TankModel {
id: _model
onModelUpdated : {
_tankList.enabled = true;
}
}
}
...
I want to check if an item of component is vissible or not but I don't know how to do this.
Here is my code but error is "ReferenceError: tagFilterPlaylist is not defined" how to solve this?
Repeater {
id: tagRepeater
model: main.playListBrowseModel
Component {
id: componentTagFilterPlaylist
BasicUI.Tag {
id: tagFilterPlaylist
tag: "playlist"
selected: true
}
}
Loader {
id: filterLoader
sourceComponent:
if (item_type === "playlist"){
console.debug("check"+tagFilterPlaylist)
if (!tagFilterPlaylist) {
tagFilterPlaylist.visible = true;
return componentTagFilterPlaylist
}
}
}
}
You can't refer to an id within a Component because you first need to have an instance of that Component. What you should do is simply keep a boolean property outside the Repeater that keeps track of whether or not you're displaying your one and only tagFilterPlaylist.
property bool playlistVisible: false
Component {
id: componentTagFilterPlaylist
...
}
Repeater {
id: tagRepeater
model: main.playListBrowseModel
Loader {
id: filterLoader
sourceComponent:
if (item_type === "playlist"){
if (!playlistVisible) {
playlistVisible = true;
return componentTagFilterPlaylist
}
}
}
}
Is there any way to get value or property from Stackview item when it popped in Qml?
I want to get the edited name in 'EditProfile.qml' when it popped to 'Profile.qml' in the below project.
main.qml
StackView {
id: stackView
Component.onCompleted: push('Profile.qml', {name : 'David'})
}
Profile.qml
Page {
property string name: ''
Column {
Text {
text: 'name' + name
}
Button {
text: 'Edit'
onClicked: stackView.push('EditProfile.qml', {name : name})
}
}
}
EditProfile.qml
Page {
property alias name: txtName.text
Column {
TextEdit {
id: txtName
text: name
}
Button {
text: 'Back'
onClicked: stackView.pop()
}
}
}
After reading QT manual carefully, I found the answer. The push function returns the item which is pushed. so:
Profile.qml
Page {
id: root
property string name: ''
Column {
Text {
text: 'name' + name
}
Button {
text: 'Edit'
onClicked: {
var item = stackView.push('EditProfile.qml', {name : name})
item.exit.connect(change);
function change(text) {
item.exit.disconnect(change);
root.name = text;
}
}
}
}
}
EditProfile.qml
Page {
signal exit(var text)
property alias name: txtName.text
Column {
TextEdit {
id: txtName
text: name
}
Button {
text: 'Back'
onClicked: {
exit(txtName.text)
stackView.pop()
}
}
}
}
Consider this C++ statement (example from docs):
QTimer::singleShot(600000, &app, SLOT(quit()));
How to do the same in .qml JavaScript, something like this QML:
Rectangle {
property int counter: 0
onCounterChanged: {
if (counter > 42) {
// do equivalent of above C++ statement here
}
}
// more code, which actually manipulates counter
}
There's the obvious solution of having separate Timer, which is then started by this JavaScript code, and I'll accept that as an answer if a one-liner is not possible. Is it?
I ended up adding this to my main.qml:
Component {
id: delayCallerComponent
Timer {
}
}
function delayCall( interval, callback ) {
var delayCaller = delayCallerComponent.createObject( null, { "interval": interval } );
delayCaller.triggered.connect( function () {
callback();
delayCaller.destroy();
} );
delayCaller.start();
}
Which can be used like this:
delayCall( 1000, function () { ... } );
Change "repeat" property to false for Timer object.
import QtQuick 1.0
Item {
Timer {
id: timer
interval: 600000
running: false
repeat: false
onTriggered: Qt.quit()
}
Rectangle {
property int counter: 0
onCounterChanged: {
if (counter > 42) {
timer.running = true
}
}
}
}
Here is how to do it using a SequentialAnimation element:
SequentialAnimation {
id: quitTimer
PauseAnimation { duration: 60000 }
ScriptAction { script: Qt.quit() }
}
Rectangle {
property int counter: 0
onCounterChanged: {
if (counter > 42) {
quitTimer.start()
}
}
}
If that's too ugly, make a component out of it:
// SingleshotTimer.qml
import QtQuick 2.0
SequentialAnimation {
property alias delay: delayAnim.duration
property alias script: scriptAction.script
PauseAnimation { id: delayAnim; duration: 10000 }
ScriptAction { id: scriptAction }
}
Using this new component gives what you want:
SingleshotTimer { id: timer; delay: 60000; script: Qt.quit() }
Rectangle {
property int counter: 0
onCounterChanged: {
if (counter > 42) {
timer.start()
}
}
}
Another option I came up with is to simply define a function like this in C++:
void QmlUtils::singleShot(int msec, QJSValue callback)
{
QTimer::singleShot(msec, this, [callback] () mutable {
if (callback.isCallable())
callback.call();
});
}
and I call it from QML with:
lqtUtils.singleShot(5000, () => console.log("Hello!"))
I then added that C++ function to my collection of "must-have" here: https://github.com/carlonluca/lqtutils/blob/master/lqtutils_ui.h#L53.
there is a timer component in QML
import QtQuick 2.0
Item {
Timer {
interval: 500; running: true; repeat: true
onTriggered: time.text = Date().toString()
}
Text { id: time }
}
for more details see the documentation
I set properties like this running: true; repeat: false;
Timer {
interval: 5000
running: true
repeat: false
onTriggered:console.log("Test");
}
I have my main.qml that contains a tabbedpane, in which, it has two tabs: tab1 and tab2.
I would like to be able to change the text from one tab to another.
If I do the same with navigationpane it works but not with tabs apparently. Is there any way I could share information between them? I've tried with signals in c++ but it doesn't work either(I guess it doesnt know the instance ?).
Any suggestion is appreciated.
main.qml:
TabbedPane {
Tab {
Tab1 {
}
}
Tab {
Tab2 {
}
}
attachedObjects: [
Tab1 {
id: tab1
},
Tab2 {
id: tab2
}
]
}
Tab1.qml:
Page {
property alias labeltab1: labeltab1
Container {
Label {
id: labeltab1
text: "label tab1"
}
Button {
id: buttontab1
text: "tab1"
onClicked: {
tab2.labeltab2.text = "This is coming from tab1"
}
}
}
}
Tab2.qml:
Page {
property alias labeltab2: labeltab2
Container {
Label {
id: labeltab2
text: "Label tab2"
}
Button {
id: buttontab2
text: "tab2"
onClicked: {
tab1.labeltab1.text = "This is coming from tab2"
}
}
}
}
I guess it's actually simpler with tabs and I found my own solution.
I noticed that momentics cannot detect that "thepane" is linkable and will not suggest its name when typing it from one of the tab. Also, a property with colon will automatically bind the value afterit, as: text: thepane.mystring
When clicking on buttons, it changes the value of mystring thus changing both labels texts.
main.qml
TabbedPane {
id: thepane
property string mystring
Tab {
Tab1 {
}
}
Tab {
Tab2 {
}
}
}
Tab1.qml
Page {
Container {
Label {
id: labeltab1
text: thepane.mystring
}
Button {
id: buttontab1
text: "tab1"
onClicked: {
thepane.mystring = "This is coming form tab1"
}
}
}
}
Tab2.qml
Page {
Container {
Label {
id: labeltab2
text: thepane.mystring
}
Button {
id: buttontab2
text: "tab2"
onClicked: {
thepane.mystring = "This is coming from tab2"
}
}
}
}
Thank you for your idea.
I changed the code. Now it is better for me, maybe for other one people :)
main.qml
TabbedPane {
id: main_Pane
property string action_1
property string action_2
Tab {
Tab1 {}
}
Tab {
Tab2 {}
}
}
Tab1.qml
Page {
Container {
Label {
text: main_Pane.action_1
}
Button {
text: "Button 1"
onClicked: {
main_Pane.action_2 = "This is action form Tab1"
}
}
}
}
Tab2.qml
Page {
Container {
Label {
text: main_Pane.action_2
}
Button {
text: "Button 2"
onClicked: {
main_Pane.action_1 = "This is action from Tab2"
}
}
}
}