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. Qt application with public QML code that user can edit

Qt application with public QML code that user can edit

Scheduled Pinned Locked Moved Solved QML and Qt Quick
10 Posts 2 Posters 2.6k 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.
  • O Offline
    O Offline
    ODБOï
    wrote on 22 Jan 2018, 15:10 last edited by ODБOï
    #1

    Hello,

    I want to allow users to change visual aspect of my application editing '.qml' files.

    I know this is possible but have no idea how. Can someone put me on the right track please ?

    I found this :

    QML files in the file system

    Files are stored without compression and encryption

    Faster to build but slower to deploy
    Stored without compression so they take more storage space
    Easy to do UI changes on the fly on target (just edit QML and restart) < this is what i need i think
    

    so how to store files without compression and encryption?

    QML files in the resource file

    Resources are compiled to the binary file making the executable file size bigger

    Slower to build but faster to deploy.
    Takes less storage space because resources are compressed by default.
    Because the executable size is bigger the program takes more memory when running.
    You can't do changes to UI without re-compiling
    

    Thx in advance
    LA

    1 Reply Last reply
    0
    • O ODБOï
      24 Jan 2018, 08:29

      @SGaist hello,
      As i said i'm trying to create a qtQuick app, with .qml files avalabls for the user (user can edit qml files)

      @SGaist said in Qt application with public QML code that user can edit:

      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.

      So I'm trying to subclass QQuickPaintedItem,

       class QMProgressBar :  public QQuickPaintedItem{
      
         // I want to read a .qml file ('user file' if it exists, otherwise the one from the resource)  create the item corresponding that qml code,  show it on the screen
         
      };
      

      then i will register my class : qmlRegisterType<QMProgressBar>("QMProgressBar", 1, 0, "Bar");

      To be able to create QMProgressBar{} in QML.

      So, for the moment in my class I'm able to load the right file, cast it to QQuickItem*, read properties :

       QQmlComponent component(&qengine, QUrl::fromUserInput(homeLocation));
       userItem = qobject_cast<QQuickItem*>(component.create());
       qDebug() << userItem->property("maxValue"); 
      

      Last thing i have to do, is to show that item.

      Thx

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

      @LeLev said in Qt application with public QML code that user can edit:

      Last thing i have to do, is to show that item.

      Ok, last thing to do was to set the visual parent of my qquickitem ! now is is working.

        userItem->setParentItem(this);
      

      @SGaist thank you very much for help!
      LA

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

        Hi,

        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.

        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 23 Jan 2018, 08:07
        1
        • S SGaist
          22 Jan 2018, 22:25

          Hi,

          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.

          O Offline
          O Offline
          ODБOï
          wrote on 23 Jan 2018, 08:07 last edited by
          #3

          @SGaist Thx!

          1 Reply Last reply
          0
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 23 Jan 2018, 08:15 last edited by
            #4

            Note that this also allows you to do a "reset" if the edits ends breaking something (and you can be sure it will at some point)

            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 23 Jan 2018, 10:52
            1
            • S SGaist
              23 Jan 2018, 08:15

              Note that this also allows you to do a "reset" if the edits ends breaking something (and you can be sure it will at some point)

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

              @SGaist thx again.

              I sublclassed QQuickPaintedItem;

              constructor:

              #include "qmprogressbar.h"
              
              QMProgressBar::QMProgressBar()
              {
              
                  QString homeLocation = QStandardPaths::locate(QStandardPaths::DocumentsLocation, QString(), QStandardPaths::LocateDirectory);
                  homeLocation.append("QMProgressBar.qml");
                  QQmlEngine qengine;
                    QFile file(homeLocation);
              
                  if( file.exists()){
                      qDebug()<< "User file found..."<< homeLocation ;
                      QQmlComponent component(&qengine,QUrl::fromUserInput(homeLocation));
                      userItem = qobject_cast<QQuickItem*>(component.create());
                      qDebug()<< userItem->property("maxValue");
                  }
                  else{
                      homeLocation = ":/QMProgressBar.qml";
                             QFile homefile(homeLocation);
                      if(homefile.exists()){
                          qDebug()<< "QRC file found..."<< homeLocation;
                       QQmlComponent component(&qengine,QUrl::fromUserInput(homeLocation));
                          userItem = qobject_cast<QQuickItem*>(component.create());
                          qDebug()<< userItem->property("maxValue");
                      }
                  }
              
                  userItem->deleteLater();
              
              }
              
              

              if file exists in writable homeLocation it will be used else
              qrc file is used. This is ok.

              Now could you please tell me how can i display this item on the screen ?

              I saw this exemple http://doc.qt.io/qt-5/qtquick-scenegraph-customgeometry-example.html
              but i can not understand what exactly i have to do ..

              Do i have to implement paint(QPainter *painter) method ?

              1 Reply Last reply
              0
              • O Offline
                O Offline
                ODБOï
                wrote on 23 Jan 2018, 14:31 last edited by ODБOï
                #6

                I did this :

                void QMProgressBar::paint(QPainter *painter){
                  //test
                      painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16); // this works
                      
                }
                

                There is a method drawPixmap( x,y,w,h,QPixmap &pm )

                so I'm trying to convert my QMProgressBar.qml to a pixmap :

                void QMProgressBar::paint(QPainter *painter){
                  
                QPixmap itemPxMap;
                     itemPxMap.load("qrc:///QMProgressBar.qml");
                     painter->drawPixmap(50,50,100,100,itemPxMap);   // this will not work : application starts and shows white screen
                
                }
                

                Is it possible to convert a .qml file to QPixmap ? Please tell me what i'm doing wrong here.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 23 Jan 2018, 21:01 last edited by
                  #7

                  What exactly are you trying to achieve ? I thought you wanted to load a QML file and run it live in your application which seems to not be what you are doing.

                  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
                  0
                  • O Offline
                    O Offline
                    ODБOï
                    wrote on 24 Jan 2018, 08:29 last edited by ODБOï
                    #8

                    @SGaist hello,
                    As i said i'm trying to create a qtQuick app, with .qml files avalabls for the user (user can edit qml files)

                    @SGaist said in Qt application with public QML code that user can edit:

                    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.

                    So I'm trying to subclass QQuickPaintedItem,

                     class QMProgressBar :  public QQuickPaintedItem{
                    
                       // I want to read a .qml file ('user file' if it exists, otherwise the one from the resource)  create the item corresponding that qml code,  show it on the screen
                       
                    };
                    

                    then i will register my class : qmlRegisterType<QMProgressBar>("QMProgressBar", 1, 0, "Bar");

                    To be able to create QMProgressBar{} in QML.

                    So, for the moment in my class I'm able to load the right file, cast it to QQuickItem*, read properties :

                     QQmlComponent component(&qengine, QUrl::fromUserInput(homeLocation));
                     userItem = qobject_cast<QQuickItem*>(component.create());
                     qDebug() << userItem->property("maxValue"); 
                    

                    Last thing i have to do, is to show that item.

                    Thx

                    O 1 Reply Last reply 24 Jan 2018, 09:28
                    0
                    • O Offline
                      O Offline
                      ODБOï
                      wrote on 24 Jan 2018, 09:19 last edited by
                      #9

                      Like this exemple : http://doc.qt.io/qt-5/qtqml-tutorials-extending-qml-example.html

                      except :

                      void PieChart::paint(QPainter *painter)
                      {
                          QPen pen(m_color, 2);
                          painter->setPen(pen);
                          painter->setRenderHints(QPainter::Antialiasing, true);
                        //  painter->drawPie(boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16);
                       //instead of  'drawPie()',  i want to drow 'userItem'
                      }
                      
                      1 Reply Last reply
                      0
                      • O ODБOï
                        24 Jan 2018, 08:29

                        @SGaist hello,
                        As i said i'm trying to create a qtQuick app, with .qml files avalabls for the user (user can edit qml files)

                        @SGaist said in Qt application with public QML code that user can edit:

                        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.

                        So I'm trying to subclass QQuickPaintedItem,

                         class QMProgressBar :  public QQuickPaintedItem{
                        
                           // I want to read a .qml file ('user file' if it exists, otherwise the one from the resource)  create the item corresponding that qml code,  show it on the screen
                           
                        };
                        

                        then i will register my class : qmlRegisterType<QMProgressBar>("QMProgressBar", 1, 0, "Bar");

                        To be able to create QMProgressBar{} in QML.

                        So, for the moment in my class I'm able to load the right file, cast it to QQuickItem*, read properties :

                         QQmlComponent component(&qengine, QUrl::fromUserInput(homeLocation));
                         userItem = qobject_cast<QQuickItem*>(component.create());
                         qDebug() << userItem->property("maxValue"); 
                        

                        Last thing i have to do, is to show that item.

                        Thx

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

                        @LeLev said in Qt application with public QML code that user can edit:

                        Last thing i have to do, is to show that item.

                        Ok, last thing to do was to set the visual parent of my qquickitem ! now is is working.

                          userItem->setParentItem(this);
                        

                        @SGaist thank you very much for help!
                        LA

                        1 Reply Last reply
                        0

                        1/10

                        22 Jan 2018, 15:10

                        • Login

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