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. QQuickPaintedItem from .qml file
Forum Updated to NodeBB v4.3 + New Features

QQuickPaintedItem from .qml file

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
12 Posts 2 Posters 3.1k Views 1 Watching
  • 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.
  • O Offline
    O Offline
    ODБOï
    wrote on 24 Jan 2018, 11:42 last edited by
    #1

    Hi,
    I have created a little test application with .qml files avalables for the user so he can edit and change visual aspect of the application.

    I dit that by subclassing 'QQuickPaintedItem' like this :
    // QMProgressBar .h

    class QMProgressBar :  public QQuickPaintedItem
    {
        Q_OBJECT
    public:
        QMProgressBar(QQuickItem *parent = 0);
    
    private:
            QQuickItem* userItem;
           // void paint(QPainter *painter);
    };
    

    //QMProgressBar.cpp

    QMProgressBar::QMProgressBar(QQuickItem *parent):QQuickPaintedItem(parent)
    {
    
        QString homeLocation = QStandardPaths::locate(QStandardPaths::DocumentsLocation, QString(), QStandardPaths::LocateDirectory);
        homeLocation.append("QML_CUSTOM_ITEM/Customizable.qml");
        QQmlEngine qengine;
        QQmlComponent component(&qengine,QUrl::fromUserInput(homeLocation));
        QFile file(homeLocation);
    
        if( file.exists()){
            qDebug()<< "User file found..."<< homeLocation ;
            userItem = qobject_cast<QQuickItem*>(component.create());
            userItem->setParentItem(this)
        }    
    }
    

    //main.cpp

    qmlRegisterType<QMProgressBar>("QMProgressBar", 1, 0, "Bar");
    

    //main.qml

     Bar{
                id:bar
                height: 150
                width: 150
            }
    

    This works but i have at least 1 probleme :

    if 'Customizable.qml' contains just Rectangles/Texts/.. (not dynamic behavior) it will work.

    exemple Customizable.qml:

    Item{
        Rectangle{
            id:r
           color : "red"
           rotation : 45
       }
    }
    

    But if 'Customizable.qml' contains some dynamic behavior, it will not work

    exemple Customizable.qml:

    Item{
        Rectangle{
            id:r
           color : "red"
           rotation : 45
       }
       Timer{
            running:true
            repeat:true
            interval : 500
            onTriggered: r.rotation+=10 // item will not rotate
        }
    }
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 24 Jan 2018, 12:31 last edited by
      #2

      Hi,

      Why not use a Loader ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      O 2 Replies Last reply 24 Jan 2018, 13:22
      1
      • S SGaist
        24 Jan 2018, 12:31

        Hi,

        Why not use a Loader ?

        O Offline
        O Offline
        ODБOï
        wrote on 24 Jan 2018, 13:22 last edited by
        #3

        @SGaist hi,
        after your comment on my previous thread
        https://forum.qt.io/topic/87077/qt-application-with-public-qml-code-that-user-can-edit/2

        "One possible way is to copy the file you want to allow editing from the resource to a suitable writable location (see QStandardPaths).
        Then you have to tell your application to load that file if it exists otherwise the one from the resource.
        "

        I though the best solution was to do this by subclassing 'QQuickPaintedItem' ...

        I will try to do the same thing using Loader, it seems easier in fact.

        Thx!

        1 Reply Last reply
        0
        • O Offline
          O Offline
          ODБOï
          wrote on 24 Jan 2018, 13:57 last edited by ODБOï
          #4

          Perfect, i dit it in 10 minutes with Loader !

          
              property Component qrcComponent
              property Component userComponent
          
          
              Component.onCompleted: {
          
                  userComponent = Qt.createComponent("file:///C:/Users/userName/Documents/QML_CUSTOM_ITEM/Customizable.qml")
                 //qrcComponent = Qt.createComponent("/Customizable.qml")
          
              }
          
              onUserComponentChanged: {
                  if(userComponent.status==Component.Ready){
                      l.sourceComponent = userComponent
                  }
                  else{
                      qrcComponent = Qt.createComponent("/Customizable.qml")
                      if(qrcComponent.status==Component.Ready){
                          l.sourceComponent = qrcComponent
                      }
                  }
              }
          
          
                  Loader{
                      id:l
                      height: 150
                      width: 150
                      anchors.centerIn: parent
                     // source: "file:///C:/Users/userName/Documents/QML_CUSTOM_ITEM/Customizable.qml" ||  "/Customizable.qml"
                  }
          

          Thx

          1 Reply Last reply
          0
          • S SGaist
            24 Jan 2018, 12:31

            Hi,

            Why not use a Loader ?

            O Offline
            O Offline
            ODБOï
            wrote on 24 Jan 2018, 14:10 last edited by
            #5

            @SGaist said in QQuickPaintedItem from .qml file:

            Why not use a Loader ?

            FinalIy i did it with Loader , but is there a way to do the same thing with my QMProgressBar class ?

            1 Reply Last reply
            0
            • O Offline
              O Offline
              ODБOï
              wrote on 24 Jan 2018, 15:13 last edited by
              #6

              On my Loader exemple, Is it possible to Reload component runtime ?

                  Button{
                      text:"reload"
                      onClicked: { /* RELOADING ? */
                          userComponent = Qt.createComponent("file:///C:/Users/lagayev/Documents/QML_CUSTOM_ITEM/Customizable.qml");
                      }
                  }
              

              If i edit 'Customizable.qml' while application is running, and click this 'reload' button 'Customizable.qml' is unchanged,
              i have to quit and restart my app to see changes. Could you tell me Why ?

              1 Reply Last reply
              0
              • O Offline
                O Offline
                ODБOï
                wrote on 24 Jan 2018, 16:02 last edited by
                #7

                I tryed to clearComponentCache as it is described here :
                http://doc.qt.io/qt-5/qqmlengine.html#clearComponentCache

                class QmlEngineManager : public QQmlApplicationEngine
                {
                    Q_OBJECT
                public:
                    QmlEngineManager();
                
                    Q_INVOKABLE void clearCache() {
                        clearComponentCache();
                        qDebug()<<"engine cleared !";
                    }
                };
                

                Then in qml :

                 Button{
                        text:"reload"
                        onClicked: { /* RELOADING ? */
                             engineManager.clearCache()
                            userComponent = Qt.createComponent("file:///C:/Users/lagayev/Documents/QML_CUSTOM_ITEM/Customizable.qml");
                        }
                    }
                

                witout success.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 24 Jan 2018, 21:53 last edited by
                  #8

                  What about destroying userComponent before you create the new one ?

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  O 1 Reply Last reply 25 Jan 2018, 11:02
                  0
                  • S SGaist
                    24 Jan 2018, 21:53

                    What about destroying userComponent before you create the new one ?

                    O Offline
                    O Offline
                    ODБOï
                    wrote on 25 Jan 2018, 11:02 last edited by
                    #9

                    @SGaist with this code, when i start my app, it will create a component from file:///C:/Users/usr/Documents/QML_CUSTOM_ITEM/Customizable.qml if that file exists, else it will create component from /Customizable.qml

                    But when app is running, if i DELETE 'Customizable.qml' file from that path (file:///C:/Users/usr/Documents/QML_CUSTOM_ITEM/Customizable.qml) , and press 'Reload' button, the same .qml file is displayed !

                    It looks like content of a given path is calculated only when the application starts..?

                    What is the probleme here ?

                       signal updateComponents()
                        Button{
                            text: "Reload"
                            onClicked: {
                                updateComponents()
                            }
                        }
                        Component.onCompleted:updateComponents()
                      
                      onUpdateComponents: {
                         var tmp =  Qt.createComponent("file:///C:/Users/usr/Documents/QML_CUSTOM_ITEM/Customizable.qml")
                         if(tmp.status===Component.Ready){
                                     l.sourceComponent = tmp
                         }
                         else{
                                 tmp=Qt.createComponent("/Customizable.qml")
                                 if(tmp.status===Component.Ready){
                                      l.sourceComponent=tmp
                                   }
                               }
                                delete(tmp)
                        }
                    
                        Loader{
                            id:l
                            height: 150
                            width: 150
                            anchors.centerIn: parent
                        }
                    
                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 25 Jan 2018, 22:36 last edited by
                      #10

                      I was rather thinking about what is described here.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      O 1 Reply Last reply 26 Jan 2018, 09:09
                      1
                      • S SGaist
                        25 Jan 2018, 22:36

                        I was rather thinking about what is described here.

                        O Offline
                        O Offline
                        ODБOï
                        wrote on 26 Jan 2018, 09:09 last edited by
                        #11

                        @SGaist Hi,
                        I did that way too, but no success because

                        when my app calls :

                          var component = Qt.createComponent("file:///C:/Users/user/Documents/QML_CUSTOM_ITEM/Destructible.qml")
                        

                        inside that directory ("file:///C:/Users/user/Documents/QML_CUSTOM_ITEM") another file is created by qt, named

                        Destructible.qmlc ( 'c' like copy ? )

                        Next call 'Qt.createComponent()' loads that 'Destructible.qmlc'

                        1 Reply Last reply
                        0
                        • S Offline
                          S Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on 26 Jan 2018, 22:35 last edited by
                          #12

                          This presentation might help.

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          1

                          7/12

                          24 Jan 2018, 16:02

                          • Login

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