Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How to get eval() to operate in the scope of QML element

How to get eval() to operate in the scope of QML element

Scheduled Pinned Locked Moved QML and Qt Quick
10 Posts 2 Posters 2.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    qttester5
    wrote on last edited by
    #1

    If I have some JS code as text and I call it in eval(), I can then use the functions defined by this statement only in the scope of where the eval() occurred. As far as I can tell, this means that any new JS definitions created from the eval are invisible to the rest of QML. Consider this QML signal handler:

    @
    Item {
    id: testitem
    onThesourceChanged: {
    eval(thesource)
    testfunction()
    }
    }@

    The testfunciton() was defined in the text "thesource" and does indeed work; but it is not in the scope of the QML element and therefore cannot be called ever again, as far as I can see. I've tried various ideas like putting the eval() in a function, or inside Component.onCompleted, etc, but I can't seem to figure out how to get anything created by the eval() to be recognized as part of the parent QML element.

    For example I want to be able to call testitem.testfunction() -- but it is not defined outside the scope of this handler.

    Can anyone assist?

    1 Reply Last reply
    0
    • X Offline
      X Offline
      Xander84
      wrote on last edited by
      #2

      Hi, maybe a little bit far fetched, but the function might be garbage collected after you call it, since you just define it inside your "onThesourceChanged" slot and call it once, it seems like a local function in a function!? Just an idea :)

      if you use eval your get somethging like this:
      @
      Item {
      id: testitem
      onThesourceChanged: {
      var testfunction = function() { ... } // after eval -> local function ?
      testfunction()
      }
      }
      @

      1 Reply Last reply
      0
      • Q Offline
        Q Offline
        qttester5
        wrote on last edited by
        #3

        You are probably right, but the question is, how to get the definitions that appear inside the text that is evaluated with eval() to actually be attached to a QML element and persist?

        1 Reply Last reply
        0
        • X Offline
          X Offline
          Xander84
          wrote on last edited by
          #4

          Well simple solution would be so save a reference to the function, so you can call it from outside, e.g.
          @
          Item {
          id: testitem
          property var testfunction // use this property to save the function you generate in your eval
          onThesourceChanged: {
          eval(thesource)
          testfunction()
          }
          }
          @
          I can't think of any easier way at the moment, but if you only have once function you can do it like this, it gets a little more complicated if you generate multiple dynamic functions...
          you can set the property from the source code your provide to eval or better return it in the source code ans use it like
          @
          testfunction = eval(thesource)
          @
          that should work, I have no idea if there is a way to define dynamic functions or properties in QML. Maybe you can research that or somebody else knows that, but I am not aware of something like that.

          1 Reply Last reply
          0
          • Q Offline
            Q Offline
            qttester5
            wrote on last edited by
            #5

            I have many functions, and their names and quantity will vary; I'm essentially loading a whole JS program at runtime via the eval. So I can't assign individual vars like this, though it is a good idea.

            1 Reply Last reply
            0
            • X Offline
              X Offline
              Xander84
              wrote on last edited by
              #6

              Ok then I have another idea, if you load a whole script do you have control over it somehow? I mean you could wrap it inside a JS object and assign that to a property?
              So same code as in my last post, just the property name changed
              @
              Item {
              id: testitem
              property var myFunctions // use this property to store your object with all functions
              onThesourceChanged: {
              myFunctions = eval(thesource)
              myFunctions.testfunction()
              }
              }
              @
              and your "thesource" looks something like
              @
              return {
              testfunction: function() { ... },
              testfunction2: function() { ... },
              testfunction3: function() { ... }
              ...
              }
              @

              Still this sounds a little weird, but I really have no idea if you can create dynamic functions property with QML. What you need is a JS lib maybe, like if you create a real .js file in QML and import it like
              @
              import "YourFunctions.js" as YourFunctions
              @
              again no idea if it would be possible to load a dynamically generated JS file like that, but that would be the best answer, if possible. And not assign the functions to a QML Item.

              1 Reply Last reply
              0
              • Q Offline
                Q Offline
                qttester5
                wrote on last edited by
                #7

                A var needs to be in JSON format, right? If you have a JS file with normal standalone definitions, those will not be assigned to JSON keys, so you can't assign the entire file to a var. I wish you could, though.

                My JS file is just a normal JS program. I cannot wrap it inside anything or assign each definition to a JSON key. I can import it in QML fine, but I want to be able to refresh this import dynamically, and using eval() seems to be one way to do this, if only I can get the scope to work out.

                1 Reply Last reply
                0
                • X Offline
                  X Offline
                  Xander84
                  wrote on last edited by
                  #8

                  I don' think the "property var" needs to be in JSON format, since Qt 5 at least it can be any JavaScript value you can assign to a local "var". before Qt 5 you couldn't e event assign a function to a "property" as far as I know, but I have done that in my app (Qt 5.2.1).
                  Well maybe someone else has an idea with your problem, if you can't use it like this. :/

                  1 Reply Last reply
                  0
                  • Q Offline
                    Q Offline
                    qttester5
                    wrote on last edited by
                    #9

                    It would be awesome if the import statement at the top of a QML file could just be reloaded at runtime. I can't find any way to do that either. It would solve my issue.

                    1 Reply Last reply
                    0
                    • Q Offline
                      Q Offline
                      qttester5
                      wrote on last edited by
                      #10

                      I found the solution. Using Qt.include() allows for dynamic reloading of a javascript file at runtime, even if that javascript file has changed.

                      1 Reply Last reply
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved