Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QStringList in QML?
QtWS25 Last Chance

QStringList in QML?

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 3 Posters 16.3k 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.
  • M Offline
    M Offline
    MScottM
    wrote on 15 Jul 2019, 12:59 last edited by
    #5

    Yes - moduleFinder.h:

    #ifndef MODULEFINDER_H
    #define MODULEFINDER_H
    
    #include <QObject>
    #include <QStringListModel>
    
    class moduleFinder : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QStringList moduleIo MEMBER m_moduleIo NOTIFY moduleIoChanged)
    
    public:
        explicit moduleFinder( QObject *parent = nullptr );
    
        QString fileName = "list.txt";
        QString module;
        QStringList ioList;
        QStringList moduleIo;    
    
        Q_INVOKABLE void loadModules();
        QStringList getIo(QString);
        int index = 0;
        int newIndex = 0;
    
    public slots:
        Q_INVOKABLE void setModule( const QString m_module );
    
    signals:
        void moduleIoChanged(const QStringList &newModuleIoList);
        
    private:
       
    };
    
    #endif // MODULEFINDER_H
    

    moduleFinder.cpp:

    #include "modulefinder.h"
    #include <QFile>
    #include <QDebug>
    
    moduleFinder::moduleFinder(QObject *parent) : QObject(parent)
    {}
    
    void moduleFinder::setModule(QString m_module) {
        module = m_module;
        getIo(module);
    }
    
    void moduleFinder::loadModules(){
        QFile moduleFile(fileName);
    
        if (!moduleFile.exists()) {
            qWarning() << "file doesn't exist!";}
        else if (!moduleFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qWarning() << "Not open"; }
        else {
            QTextStream textStream(&moduleFile);
            while (!textStream.atEnd())
                ioList << textStream.readLine();
            moduleFile.close();
        }   
    }
    
    QStringList moduleFinder::getIo(QString myModule) {
        //qDebug()<<myModule;
        int lines = ioList.length();
        QString moduleId = myModule;
        for (int i=0;i<lines;i++) {
            //qDebug()<< "IO List" <<ioList.at(i);
            if (ioList.at(i).contains(moduleId)) { // if module is found in list
                index = i; // get index of position in list
            }
        }
        newIndex = index + 32;
        for (int y=index+1; y<newIndex+1; ++y) { // and copy relevant lines into new list
            moduleIo << ioList.at(y); //   <-this is the QStringList I want to access
        }    
        emit moduleIoChanged(m_moduleIo);
        //qDebug()<< moduleIo;
    }
    

    loadModules() is run once from main.cpp when the program starts.

    J 1 Reply Last reply 15 Jul 2019, 13:12
    0
    • M MScottM
      15 Jul 2019, 12:59

      Yes - moduleFinder.h:

      #ifndef MODULEFINDER_H
      #define MODULEFINDER_H
      
      #include <QObject>
      #include <QStringListModel>
      
      class moduleFinder : public QObject
      {
          Q_OBJECT
          Q_PROPERTY(QStringList moduleIo MEMBER m_moduleIo NOTIFY moduleIoChanged)
      
      public:
          explicit moduleFinder( QObject *parent = nullptr );
      
          QString fileName = "list.txt";
          QString module;
          QStringList ioList;
          QStringList moduleIo;    
      
          Q_INVOKABLE void loadModules();
          QStringList getIo(QString);
          int index = 0;
          int newIndex = 0;
      
      public slots:
          Q_INVOKABLE void setModule( const QString m_module );
      
      signals:
          void moduleIoChanged(const QStringList &newModuleIoList);
          
      private:
         
      };
      
      #endif // MODULEFINDER_H
      

      moduleFinder.cpp:

      #include "modulefinder.h"
      #include <QFile>
      #include <QDebug>
      
      moduleFinder::moduleFinder(QObject *parent) : QObject(parent)
      {}
      
      void moduleFinder::setModule(QString m_module) {
          module = m_module;
          getIo(module);
      }
      
      void moduleFinder::loadModules(){
          QFile moduleFile(fileName);
      
          if (!moduleFile.exists()) {
              qWarning() << "file doesn't exist!";}
          else if (!moduleFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
              qWarning() << "Not open"; }
          else {
              QTextStream textStream(&moduleFile);
              while (!textStream.atEnd())
                  ioList << textStream.readLine();
              moduleFile.close();
          }   
      }
      
      QStringList moduleFinder::getIo(QString myModule) {
          //qDebug()<<myModule;
          int lines = ioList.length();
          QString moduleId = myModule;
          for (int i=0;i<lines;i++) {
              //qDebug()<< "IO List" <<ioList.at(i);
              if (ioList.at(i).contains(moduleId)) { // if module is found in list
                  index = i; // get index of position in list
              }
          }
          newIndex = index + 32;
          for (int y=index+1; y<newIndex+1; ++y) { // and copy relevant lines into new list
              moduleIo << ioList.at(y); //   <-this is the QStringList I want to access
          }    
          emit moduleIoChanged(m_moduleIo);
          //qDebug()<< moduleIo;
      }
      

      loadModules() is run once from main.cpp when the program starts.

      J Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 15 Jul 2019, 13:12 last edited by
      #6

      @MScottM
      I'm surprised this actually compiles, as your class has no member m_moduleIo the member variable is called moduleIo


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      1
      • M Offline
        M Offline
        MScottM
        wrote on 15 Jul 2019, 16:51 last edited by
        #7

        Oh, I put it under 'private':

        private:
            QStringList m_moduleIo;
        

        I had been trying a couple different things to get something to work - I copied and pasted the code above from between a change I had tried.

        J 1 Reply Last reply 16 Jul 2019, 06:13
        0
        • M MScottM
          15 Jul 2019, 16:51

          Oh, I put it under 'private':

          private:
              QStringList m_moduleIo;
          

          I had been trying a couple different things to get something to work - I copied and pasted the code above from between a change I had tried.

          J Offline
          J Offline
          J.Hilk
          Moderators
          wrote on 16 Jul 2019, 06:13 last edited by
          #8

          @MScottM
          I have some difficulties to follow your problem.

          Does this simple example help you?

          //main.cpp
          #include <QApplication>
          #include <QQmlApplicationEngine>
          
          #include "myclass.h"
          #include "QQmlContext"
          
          int main(int argc, char *argv[])
          {
              QApplication app(argc, argv);
          
              QQmlApplicationEngine engine;
          
              myClass mClass;
          
              engine.rootContext()->setContextProperty("cppListModel", &mClass);
          
              engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
              if (engine.rootObjects().isEmpty())
                  return -1;
          
              return app.exec();
          }
          
          //main.qml
          import QtQuick 2.9
          import QtQuick.Window 2.2
          import QtQuick.Controls 2.5
          
          Window {
              visible: true
              width: 640
              height: 480
              title: qsTr("Hello World")
          
              id:root
          
          
              ListView{
                  id: listView
                  anchors.fill: parent
          
                  model: cppListModel.myListModel
                  delegate:Text {
                      text: modelData
                      color: index % 2 ? "red" : "blue"
                  }
              }
          }
          
          
          //myClass
          #ifndef MYCLASS_H
          #define MYCLASS_H
          
          #include <QObject>
          
          class myClass : public QObject
          {
              Q_OBJECT
              Q_PROPERTY(QStringList myListModel READ myListModel WRITE setMyListModel NOTIFY myListModelChanged)
          public:
              explicit myClass(QObject *parent = nullptr) :QObject(parent)
              {
                  setMyListModel({"Item1", "Item2", "Item3", "Item4"});
              }
          
          
              QStringList myListModel() const
              {
                  return m_myListModel;
              }
          
          signals:
          
              void myListModelChanged(QStringList myListModel);
          
          public slots:
          
          
          void setMyListModel(QStringList myListModel)
          {
              if (m_myListModel == myListModel)
                  return;
          
              m_myListModel = myListModel;
              emit myListModelChanged(m_myListModel);
          }
          
          private:
          
          QStringList m_myListModel;
          };
          
          #endif // MYCLASS_H
          

          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          0
          • M Offline
            M Offline
            MScottM
            wrote on 16 Jul 2019, 13:36 last edited by
            #9

            Hi @J-Hilk,

            Thank you for your example - I apologize for not being more clear in what I'm trying to do. I have a GUI that I want to display the inputs and outputs of the modules of a PLC, so that when a user clicks the module button, the main page updates with that modules' list of I/O.

            An over-simplified example:

            0_1563283804617_9963df82-e5c0-4373-a592-cb0c69e47631-image.png

            I can't get a ListView to work because it displays the whole list at a time, so I am trying to access a QStringList by index and put each indexes text in a corresponding label.

            I hope that better explains the problem I'm having!

            Best regards.

            J 1 Reply Last reply 17 Jul 2019, 04:51
            0
            • M Offline
              M Offline
              MScottM
              wrote on 16 Jul 2019, 20:52 last edited by
              #10

              I've made some progress following a different track!

              I was able to bring the QStringList into QML by using a function to create an array:

              Button {
                      id: clickme
                      x: 170
                      y: 0
                      visible: true
                      height: 100
                      width: 300
                      text: "click me"
                      onClicked: {setModule( "Module1" ); readlistValues.readValues(modFinder.moduleIo);
                      }
                  }
                  onSetModule: { modFinder.setModule(lblMsg) }    
              

              I had to create a property for each index value:

              property string label1Text: ""
              

              then assign them:

              Item {
                      id: readlistValues
                      function readValues(anArray) {
                          for (var i=0; i<32; i++)
                              console.log("list: ", anArray[i])
                              label1Text = anArray[0]
                      }
                  }
              

              Now 'anArray' contains my list!! And I can assign the text as I hoped.

              Label {
                      id: myLabel
                      x: 270
                      y: 106
                      width: 100
                      height: 50
                      text: label1Text
                      horizontalAlignment: Text.AlignHCenter
                      verticalAlignment: Text.AlignVCenter
                  }
              

              I followed information on this page:
              Data Type conversion Between QML and c++

              I'm sure I need to test this more, but I'm getting closer!

              1 Reply Last reply
              0
              • M MScottM
                16 Jul 2019, 13:36

                Hi @J-Hilk,

                Thank you for your example - I apologize for not being more clear in what I'm trying to do. I have a GUI that I want to display the inputs and outputs of the modules of a PLC, so that when a user clicks the module button, the main page updates with that modules' list of I/O.

                An over-simplified example:

                0_1563283804617_9963df82-e5c0-4373-a592-cb0c69e47631-image.png

                I can't get a ListView to work because it displays the whole list at a time, so I am trying to access a QStringList by index and put each indexes text in a corresponding label.

                I hope that better explains the problem I'm having!

                Best regards.

                J Offline
                J Offline
                J.Hilk
                Moderators
                wrote on 17 Jul 2019, 04:51 last edited by
                #11

                @MScottM

                like this ? (I only changed the main.qml from the previous example)

                import QtQuick 2.9
                import QtQuick.Window 2.2
                import QtQuick.Controls 2.5
                
                Window {
                    visible: true
                    width: 640
                    height: 480
                    title: qsTr("Hello World")
                
                    id:root
                
                
                    Button{
                        id:list1
                        anchors{
                            left:parent.left
                            top:parent.top
                            right:parent.horizontalCenter
                            margins: 2
                            rightMargin: 1
                        }
                        height: width / 3
                
                        text: qsTr("Set Model1")
                
                        onClicked:cppListModel.myListModel = ["Left 1", "Left 2"]
                        background: Rectangle{
                            color: cppListModel.myListModel[0] === "Left 1" ? "red" : "grey"
                        }
                    }
                
                    Button{
                        id:list2
                        anchors{
                            left:parent.horizontalCenter
                            top:parent.top
                            right:parent.right
                            margins: 2
                            leftMargin: 1
                        }
                        height: width / 3
                
                        text:  qsTr("Set Model2")
                
                        onClicked:cppListModel.myListModel = ["Right 1", "Right 2"]
                
                        background: Rectangle{
                            color: cppListModel.myListModel[0] === "Right 1" ? "red" : "grey"
                        }
                    }
                
                    Text {
                        id: entry1
                        text: cppListModel.myListModel[0]
                
                        anchors{
                            left: parent.left
                            right: parent.right
                            top: list1.bottom
                            margins: 2
                        }
                        height: list1.height
                        verticalAlignment: Text.AlignVCenter
                        horizontalAlignment: Text.AlignHCenter
                    }
                    Text {
                        id: entry2
                        text: cppListModel.myListModel[1]
                
                        anchors{
                            left: parent.left
                            right: parent.right
                            top: entry1.bottom
                            margins: 2
                        }
                        height: list1.height
                
                        verticalAlignment: Text.AlignVCenter
                        horizontalAlignment: Text.AlignHCenter
                    }
                }
                

                0_1563339030826_9779f82f-26ed-4c4a-bab3-3a534d28e954-image.png

                0_1563339041241_027063d4-1562-48a2-a9bb-5a0f12d19d4f-image.png

                0_1563339052858_85112240-72a7-4654-951a-a6c867c711d8-image.png


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                1 Reply Last reply
                0
                • M Offline
                  M Offline
                  MScottM
                  wrote on 17 Jul 2019, 12:54 last edited by MScottM
                  #12

                  Hi @J-Hilk,

                  That is the right behavior, but not the way I'm hoping to go about it. It looks like you are updating the list from the QML button?

                  In my 'real' application there will be something like 30 pieces of information to update on each button press, and like 20 possible modules (as I said - my example was over-simplified!). That is why I'm hoping to use a text file. Something like a config file that can be changed by a user as needed to update the I/O lists.

                  I think I can actually mark this one as solved, as I can now access the list from the QML side and set my labels' text. Now my issue is that even though the list updates on the c++ side, it doesn't change in QML after the first button press.

                  Shall I open a new question?

                  J 1 Reply Last reply 17 Jul 2019, 13:00
                  0
                  • M MScottM
                    17 Jul 2019, 12:54

                    Hi @J-Hilk,

                    That is the right behavior, but not the way I'm hoping to go about it. It looks like you are updating the list from the QML button?

                    In my 'real' application there will be something like 30 pieces of information to update on each button press, and like 20 possible modules (as I said - my example was over-simplified!). That is why I'm hoping to use a text file. Something like a config file that can be changed by a user as needed to update the I/O lists.

                    I think I can actually mark this one as solved, as I can now access the list from the QML side and set my labels' text. Now my issue is that even though the list updates on the c++ side, it doesn't change in QML after the first button press.

                    Shall I open a new question?

                    J Offline
                    J Offline
                    J.Hilk
                    Moderators
                    wrote on 17 Jul 2019, 13:00 last edited by
                    #13

                    @MScottM said in QStringList in QML?:

                    It looks like you are updating the list from the QML button

                    yes, but it doesn't matter what updates the list, as long as setMyListModelis called

                    I think I can actually mark this one as solved, as I can now access the list from the QML side and set my labels' text. Now my issue is that even though the list updates on the c++ side, it doesn't change in QML after the first button press.

                    hey, at least progress ;)

                    Shall I open a new question?

                    You can, but this could continue as well

                    Can you create a minimal compellable example? Should simplify things drastically 😉


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    1 Reply Last reply
                    1
                    • M Offline
                      M Offline
                      MScottM
                      wrote on 17 Jul 2019, 13:27 last edited by
                      #14

                      I figured out what is happening! It's in this function:

                      QStringList moduleFinder::getIo(QString myModule) {
                          //qDebug() << "my Module from QML" << myModule; 
                          int lines = ioList.length();
                          //qDebug() << "lines:" << lines;                
                          QString moduleId = myModule;
                          for (int i=0;i<lines;i++) {
                              //qDebug() << "IO List" << ioList.at(i);
                              if (ioList.at(i).contains(moduleId)) {      
                                  index = i;                             
                              }
                          }
                          newIndex = index + 32;
                          qDebug()<<"Index:" << index;                   
                          qDebug()<<"New Index:" << newIndex;             
                          for (int y=index+1; y<newIndex+1; ++y) {
                        // PROBLEM IS HERE
                        //m_moduleIo is being appended with a new list each time
                              m_moduleIo << ioList.at(y);
                        // I need to check and clear it at each access, but not sure how!?
                              qDebug() << "io List" << ioList.at(y);      
                          }
                          emit moduleIoChanged(m_moduleIo);              
                          qDebug()<< "m_moduleIO" << m_moduleIo;          
                          return m_moduleIo;
                          //emit moduleIoChanged(m_moduleIo);
                      }
                      
                      
                      1 Reply Last reply
                      0
                      • M Offline
                        M Offline
                        MScottM
                        wrote on 17 Jul 2019, 22:46 last edited by
                        #15

                        Update:

                        <smacks own forehead>

                        QStringList moduleFinder::getIo(QString myModule) {   
                            int lines = ioList.length();            
                            QString moduleId = myModule;
                            for (int i=0;i<lines;i++) {        
                                if (ioList.at(i).contains(moduleId)) {      
                                    index = i;                             
                                }
                            }
                            newIndex = index + 32;    
                            m_moduleIo.clear();  //<- RESET BEFORE EACH TIME THROUGH      
                            for (int y=index+1; y<newIndex+1; ++y) {  
                                m_moduleIo << ioList.at(y);  
                                qDebug() << "io List" << ioList.at(y);      
                            }
                            emit moduleIoChanged(m_moduleIo);          
                            return m_moduleIo;    
                        }
                        

                        It all works as I hoped now.

                        1 Reply Last reply
                        0

                        14/15

                        17 Jul 2019, 13:27

                        • Login

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