Page 2 of 2 FirstFirst 12
Results 21 to 37 of 37

Thread: Qt 5.4 - Scriptable Qml Application

  1. #21
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt 5.4 - Scriptable Qml Application

    Quote Originally Posted by motaito View Post
    The second snippet from above actually works. However, this
    Qt Code:
    1. Component {
    2. id: networkManager
    3. url: "../network/NetworkManagerQml.qml"
    4. }
    To copy to clipboard, switch view to plain text mode 
    doesn't work as expected.
    Yeah, it's incorrect. You'd need to use Loader instead of that. Component defines a component inline, not refers to an external component. Which is actually pretty stupid that there is no element to load an external component like that I guess you could declare a Component with a Loader inside but then your actual component would have to inherit Item.

    As for your question regarding QtObject -- yes, it was a general idea. I'd probably create a dedicated element for this purpose so that I'm sure all implementations have correct API.
    Last edited by wysota; 16th April 2015 at 22:18.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  2. #22
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    Quote Originally Posted by motaito View Post
    The second snippet from above actually works. However, this
    Qt Code:
    1. Component {
    2. id: networkManager
    3. url: "../network/NetworkManagerQml.qml"
    4. }
    To copy to clipboard, switch view to plain text mode 
    doesn't work as expected. See error above. But that's ok I can load the object in a function.
    Qt Code:
    1. Component {
    2. NetworkManagerQml {
    3. }
    4. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  3. #23
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt 5.4 - Scriptable Qml Application

    Quote Originally Posted by anda_skoa View Post
    Qt Code:
    1. Component {
    2. NetworkManagerQml {
    3. }
    4. }
    To copy to clipboard, switch view to plain text mode 
    The point is to be able to dynamically choose the component so this will of course work but will not do the job of solving the original problem.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  4. #24
    Join Date
    Apr 2015
    Posts
    26
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    @wysota
    I have been playing with this for a while and made some test. So far it's a much better solution than what I had initially. I am very grateful that you took the time to explain everything and provided all the help!

    Component defines a component inline, not refers to an external component. Which is actually pretty stupid that there is no element to load an external component like that
    I was also thinking that you should be able to just have a path to an external component and load it that way. Then again there is
    Qt Code:
    1. import "some.qml" as ComponentName
    To copy to clipboard, switch view to plain text mode 
    which provides that functionality. The problem with this is that you have to provide an absolute path for components that are not in the qrc: resources. Since an import can not have a relative or dynamically build path there really should be an option to directly load/link a component based on an url. It would make some things easier.


    @anda_skoa
    That would essentially hard code it to one specific component. I need to dynamically load different qml files depending on the desired task. The path "../network/NetworkManagerQml.qml" was only there to point out it doesn't work. Technically it would be more like this:

    Qt Code:
    1. Component {
    2. id: networkManager
    3. url: resolvePath(someTask);
    4. }
    5.  
    6. function resolvePath(someTask) {
    7. // get path to some qml file. Where the qml file
    8. // can be different depending on the desired task
    9. }
    To copy to clipboard, switch view to plain text mode 

    But that leads to the same problem. I neglected to go into more details because I thought that would be clear based on the ongoing discussion. I should have been more specific.

    So far this

    Qt Code:
    1. function loadRresource(requiredTask)
    2. {
    3. // get path to qml file depending on the task
    4. var path = resolvePath(requiredTask);
    5.  
    6. var component = Qt.createComponent(path);
    7. if (component.status == Component.Ready) {
    8. var obj = component.createObject(myText);
    9. if (null == obj)
    10. console.log("Error creating component: " + component.errorString());
    11. else
    12. {
    13. // this is the tricky part... The obj might need some sort of setup to work
    14. // find a common way to initialize various components. e.g. setting up signals and slots
    15. obj.someSetupFunctionHook();
    16. }
    17. }
    18. else
    19. console.log("Error loading component " + component.errorString());
    20. }
    To copy to clipboard, switch view to plain text mode 
    seams to work best.


    p.s. I will make sure I got it right before I mark the thread as solved. But so far I'm pretty happy with the result.

  5. #25
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt 5.4 - Scriptable Qml Application

    Quote Originally Posted by motaito View Post
    @wysota
    I have been playing with this for a while and made some test. So far it's a much better solution than what I had initially. I am very grateful that you took the time to explain everything and provided all the help!

    I was also thinking that you should be able to just have a path to an external component and load it that way. Then again there is
    Qt Code:
    1. import "some.qml" as ComponentName
    To copy to clipboard, switch view to plain text mode 
    which provides that functionality. The problem with this is that you have to provide an absolute path for components that are not in the qrc: resources. Since an import can not have a relative or dynamically build path there really should be an option to directly load/link a component based on an url. It would make some things easier.
    javascript Code:
    1. //ExternalComponent.qml
    2. import QtQuick 2.0
    3.  
    4. QtObject {
    5. id: root
    6. readonly property real progress: 0
    7. readonly property int status: Component.Null
    8. property string url
    9.  
    10. function createObject(parent, properties) {
    11. if(__cmp === null) return undefined
    12. return __cmp.createObject(parent, properties)
    13. }
    14. function errorString() {
    15. if(__cmp === null) return ""
    16. return __cmp.errorString()
    17. }
    18.  
    19. property bool _initialized: false
    20. property var __cmp: null
    21.  
    22. onUrlChanged: __maybeInitComponent()
    23.  
    24. Component.onCompleted: {
    25. __initialized = true
    26. __maybeInitComponent()
    27. }
    28. function __maybeInitComponent() {
    29. if(!__initialized) return
    30. if(url === "") { __cmp = null; return; }
    31. __cmp = Qt.createComponent(url)
    32. __cmp.statusChanged.connect(function(st) { root.status = st; })
    33. __cmp.progressChanged.connect(function(pr) { root.progress = pr; })
    34. status = __cmp.status
    35. progress = __cmp.progress
    36. }
    37. }
    To copy to clipboard, switch view to plain text mode 

    Not tested
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #26
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    Quote Originally Posted by motaito View Post
    @anda_skoa
    That would essentially hard code it to one specific component. I need to dynamically load different qml files depending on the desired task. The path "../network/NetworkManagerQml.qml" was only there to point out it doesn't work.
    Then just use the "source" property of the Loader instead of the "sourceComponent" property.
    The latter is for declaring components using Component, the former is for your use case, i.e. specifying the element using an URL.

    Quote Originally Posted by motaito View Post
    Technically it would be more like this:

    Qt Code:
    1. Component {
    2. id: networkManager
    3. url: resolvePath(someTask);
    4. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. Loader {
    2. source: resolvePath(someTask);
    3. }
    To copy to clipboard, switch view to plain text mode 

    Cheers,
    _

  7. #27
    Join Date
    Apr 2015
    Posts
    26
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    @wysota
    If it doesn't exist, you can always build it yourself While that's an interesting approach, does it actually make it easier than loading the component in a JavaScript function?

    @anda_skoa
    A Loader might be working for me. Right now I have my tasks in a list. If I click on an item, the component is created. It then makes it's task and deletes itself again. Would that also work when I just clear the source from the Loader (source: "") after the task is completed? I'll try it later when I'm back at at home. Also, I'm unsure this is ideal form me because I need to hook up some signals. What if they are not always the same for each qml file that gets loaded. As far as I know the loader requires something like this:
    Qt Code:
    1. Item {
    2. Loader {
    3. id: myLoader
    4. source: "MyItem.qml"
    5. }
    6.  
    7. Connections {
    8. target: myLoader.item
    9. onSignal: slot(arg) // these need to be flexible
    10. }
    11. }
    To copy to clipboard, switch view to plain text mode 
    in a JavaScript I can adjust the object creation based on the task. Yet I still have the option to load just one qml file. With a Loader I might need to do something like:
    Qt Code:
    1. Item {
    2. Loader {
    3. id: loader0
    4. source: ""
    5. }
    6.  
    7. Connections {
    8. target: loader0.item
    9. onSignal: slot(arg)
    10. }
    11.  
    12. Loader {
    13. id: loader1
    14. source: ""
    15. }
    16.  
    17. Connections {
    18. target: loader1.item
    19. onOtherSignal: otherSlot(arg1, arg2)
    20. }
    21.  
    22. // add loader placeholders as needed
    23.  
    24. function performTask(task)
    25. {
    26. // clear loaders, not sure that actually works...
    27. loader0.source = "";
    28. loader1.source = "";
    29.  
    30. // load necessary qml
    31. if(1 == task)
    32. loader0.source = "some.qml"
    33. else
    34. loader1.source = "other.qml"
    35. }
    36. }
    To copy to clipboard, switch view to plain text mode 
    Can a loader be cleared like that? Does then the unneeded Loader take up memory? Technically it also is some object instance so it probably should, even if just a little, right?

  8. #28
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt 5.4 - Scriptable Qml Application

    Note: While Loader itself is an Item, it can actually load objects which are not items themselves (at least that's what the docs claim).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. #29
    Join Date
    Apr 2015
    Posts
    26
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    And I just found the answer to my previous question in the docs as well
    If the source or sourceComponent changes, any previously instantiated items are destroyed. Setting source to an empty string or setting sourceComponent to undefined destroys the currently loaded object, freeing resources and leaving the Loader empty.
    I guess I'll just try it and see which works best for me.

  10. #30
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    Quote Originally Posted by motaito View Post
    Would that also work when I just clear the source from the Loader (source: "") after the task is completed?
    Yes. Also when "active" is set to false.

    Quote Originally Posted by motaito View Post
    As far as I know the loader requires something like this:
    Qt Code:
    1. Item {
    2. Loader {
    3. id: myLoader
    4. source: "MyItem.qml"
    5. }
    6.  
    7. Connections {
    8. target: myLoader.item
    9. onSignal: slot(arg) // these need to be flexible
    10. }
    11. }
    To copy to clipboard, switch view to plain text mode 
    I am not sure what you mean with "this" in "requires this".
    You mean usage of a Connections element?
    If so instead of what? Calling connect on the signal and passing the slot?

    Cheers,
    _

  11. The following user says thank you to anda_skoa for this useful post:

    motaito (17th April 2015)

  12. #31
    Join Date
    Apr 2015
    Posts
    26
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    I am not sure what you mean with "this" in "requires this".
    You mean usage of a Connections element?
    If so instead of what? Calling connect on the signal and passing the slot?
    I meant in order to hook up a signal-slot connection that a qml file might need. I am just wondering if I could load different qml files where they have different signals that they emit. In a JavaScript I can connect the signals to slots as needed. But I'm not sure how to do that with a Loader, because it seams that the connection has to be done in the "Connections {}" element. I don't think I can define one single Loader and have variable amounts of signal-slot connections depending on the qml file that gets loaded. Or is that possible?

    E.g. some qml file emits signals to update a progress bar, when the task is done it sends a signal to update a text. Another qml might not need the progress bar and only sends a signal to update a text.

    Would I have to pre-define the slots in the "Connections {}"? How would I treat such a slot if a loaded qml file wont need it?
    Qt Code:
    1. Connections {
    2. onProgress: updateProgressBar(value) // how to treat this if it's not needed by one of the qml files?
    3. onText: showText(text)
    4. }
    To copy to clipboard, switch view to plain text mode 
    Can I just ignore it because the file would never emit a signal, or would I have to somehow clear the connection?

    I am probably over thinking the issue... But you made me curious. I like to tidy up everything. Having unneeded parts leaves me restless I probably have to look at it more like an interface that allows for certain options even if one of the loaded qml files won't need all of them. But will the Loader take care of it on it's own?

  13. #32
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt 5.4 - Scriptable Qml Application

    Quote Originally Posted by motaito View Post
    I meant in order to hook up a signal-slot connection that a qml file might need. I am just wondering if I could load different qml files where they have different signals that they emit. In a JavaScript I can connect the signals to slots as needed. But I'm not sure how to do that with a Loader, because it seams that the connection has to be done in the "Connections {}" element. I don't think I can define one single Loader and have variable amounts of signal-slot connections depending on the qml file that gets loaded. Or is that possible?
    Since the element being loaded knows what signals it requires (or provides) it is the one who should be responsible for making those connections.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  14. #33
    Join Date
    Apr 2015
    Posts
    26
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    Meanwhile I tested it. The loader works pretty great.
    Qt Code:
    1. // foo.qml
    2. Item {
    3. id: root
    4. signal foo(string txt)
    5. anchors.fill: parent
    6.  
    7. MouseArea {
    8. anchors.fill: parent
    9. onClicked: {
    10. root.foo("foo clicked");
    11. }
    12. }
    13. }
    14.  
    15. // bar.qml
    16. Item {
    17. id: root
    18. signal bar(string txt)
    19. signal baz(string txt)
    20. anchors.fill: parent
    21.  
    22. MouseArea {
    23. anchors.fill: parent
    24. onClicked: {
    25. root.bar("bar clicked");
    26. root.baz("baz clicked");
    27. }
    28. }
    29. }
    30.  
    31. // a qml with a loader
    32. Loader {
    33. id: loader
    34. source: ""
    35. }
    36. Connections {
    37. onFoo: textFoo.text = txt // some text component
    38. onBar: textBar.text = txt // some text component
    39. onBaz: textBaz.text = txt // some text component
    40. }
    41.  
    42. // execute on some mouse click
    43. function build()
    44. {
    45. if("foo.qml" == loader.source)
    46. loader.source = "bar.qml"
    47. else
    48. loader.source = "foo.qml"
    49. }
    To copy to clipboard, switch view to plain text mode 
    It behaves as expected without having to set up anything further. No manual hooking of signal to slots is required. However, if foo.qml gets set as source I have a debug output like:
    Qt Code:
    1. QML Connections: Cannot assign to non-existent property "onBar"
    2. QML Connections: Cannot assign to non-existent property "onBaz"
    To copy to clipboard, switch view to plain text mode 
    and likewise if I set bar.qml as source I have:
    Qt Code:
    1. QML Connections: Cannot assign to non-existent property "onFoo"
    To copy to clipboard, switch view to plain text mode 
    I don't know if I can savely ignore these outputs as they are expected. I am not sure that's good. What do you think, should I just ignore the warrnings and use a Loader?

  15. #34
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt 5.4 - Scriptable Qml Application

    Your Connections element lacks a target. There is also ignoreUnknownSignals property that will prevent such warnings.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  16. The following user says thank you to wysota for this useful post:

    motaito (17th April 2015)

  17. #35
    Join Date
    Apr 2015
    Posts
    26
    Thanks
    2
    Qt products
    Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application [SOLVED]

    There is also ignoreUnknownSignals property that will prevent such warnings.
    Dame, it is so much easier to find stuff in the docu if you know what to look for.
    ignoreUnknownSignals : bool
    Normally, a connection to a non-existent signal produces runtime errors.

    If this property is set to true, such errors are ignored. This is useful if you intend to connect to different types of objects, handling a different set of signals for each object.
    So, it's a fairly common thing with a solution ready and not really an issue. Exactly what I was missing.

    Thanks to all the help and tips in this thread I have significantly reduced and cleaned up my code. Furthermore, I improved on how to use and understand qml as a declarative environment. I very much appreciate the help from everyone! I think I mark the thread as solved now. I have everything I was looking for and more. The help form everybody is very much appreciated. A special Thanks to wysota for all the details, explanations an code snippets. Thanks again!

    Edit: I will mark the thread as solved, as soon as I find out how
    Last edited by motaito; 17th April 2015 at 18:35.

  18. #36
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,360
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Qt 5.4 - Scriptable Qml Application [SOLVED]

    Quote Originally Posted by motaito View Post
    Edit: I will mark the thread as solved, as soon as I find out how
    Eeem... there is no way to do that currently
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  19. #37
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Qt 5.4 - Scriptable Qml Application

    Quote Originally Posted by motaito View Post
    I meant in order to hook up a signal-slot connection that a qml file might need. I am just wondering if I could load different qml files where they have different signals that they emit. In a JavaScript I can connect the signals to slots as needed. But I'm not sure how to do that with a Loader, because it seams that the connection has to be done in the "Connections {}" element.
    I know this is already solved, but remember that the Loader also has signals and a signal handler is a JavaScript context.
    So even if Connections would not have been able to do what you need, you could still have done your connections in the Loader's onLoaded handler.

    Cheers,
    _

Similar Threads

  1. Replies: 4
    Last Post: 19th November 2012, 14:35
  2. Replies: 3
    Last Post: 28th October 2011, 23:24
  3. Replies: 2
    Last Post: 7th September 2011, 13:12
  4. Replies: 1
    Last Post: 30th May 2011, 13:46
  5. Replies: 3
    Last Post: 6th January 2010, 16:55

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.