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 Update on Monday, May 27th 2025

QQuickPaintedItem from .qml file

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
12 Posts 2 Posters 3.1k 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.
  • ODБOïO Offline
    ODБOïO Offline
    ODБOï
    wrote on 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
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on 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

      ODБOïO 2 Replies Last reply
      1
      • SGaistS SGaist

        Hi,

        Why not use a Loader ?

        ODБOïO Offline
        ODБOïO Offline
        ODБOï
        wrote on 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
        • ODБOïO Offline
          ODБOïO Offline
          ODБOï
          wrote on 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
          • SGaistS SGaist

            Hi,

            Why not use a Loader ?

            ODБOïO Offline
            ODБOïO Offline
            ODБOï
            wrote on 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
            • ODБOïO Offline
              ODБOïO Offline
              ODБOï
              wrote on 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
              • ODБOïO Offline
                ODБOïO Offline
                ODБOï
                wrote on 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
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 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

                  ODБOïO 1 Reply Last reply
                  0
                  • SGaistS SGaist

                    What about destroying userComponent before you create the new one ?

                    ODБOïO Offline
                    ODБOïO Offline
                    ODБOï
                    wrote on 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
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 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

                      ODБOïO 1 Reply Last reply
                      1
                      • SGaistS SGaist

                        I was rather thinking about what is described here.

                        ODБOïO Offline
                        ODБOïO Offline
                        ODБOï
                        wrote on 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
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on 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

                          • Login

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