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. Binding list from C++ to QML
QtWS25 Last Chance

Binding list from C++ to QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qml binding
25 Posts 3 Posters 13.5k 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.
  • T TonyN
    20 Oct 2015, 22:33

    I am quite new to Qt (2 months). Basically I have items that will be displayed in a grid on a page, in a scroll-able view of pages. Most of the examples I found deal with models inside QML. I have items data from a file, thus the models must be from C++ side.
    So far I chose ListView to be my pages scroll view and GridLayout to provide items placement. I chose GridLayout because it allows me to put item anywhere on the grid with extend properties row and column for the items. My models are derived from QAbstractListModel. So far my code is running but does not do anything (obviously). I put some code here, but I think instead try to get my probably "not so right" code to work. Please give me some clue/sample code to work with instead. I still need the UI component to represent item; it can be just a rectangle for now.

    Thanks,

    Button_model.h

    class Button_model : public QObject
    {
        Q_OBJECT
    
        Q_PROPERTY(QString DisplayText READ DisplayText WRITE setDisplayText NOTIFY DisplayTextChanged)
        QString m_DisplayText;
    
        Q_PROPERTY(int Page READ Page WRITE setPage NOTIFY PageChanged)
        int m_Page;
    
        Q_PROPERTY(int Row READ Row WRITE setRow NOTIFY RowChanged)
        int m_Row;
    
        Q_PROPERTY(int Col READ Col WRITE setCol NOTIFY ColChanged)
        int m_Col;
    
    public:
        explicit Button_model(QObject *parent = 0);
    
        QString DisplayText() const
        {
            return m_DisplayText;
        }
    
        int Page() const
        {
            return m_Page;
        }
    
        int Row() const
        {
            return m_Row;
        }
    
        int Col() const
        {
            return m_Col;
        }
    
    signals:
        void DisplayTextChanged(QString DisplayText);
        void PageChanged(int Page);
        void RowChanged(int Row);
        void ColChanged(int Col);
    
    public slots:
        void setDisplayText(QString DisplayText)
        {
            if (m_DisplayText == DisplayText)
                return;
    
            m_DisplayText = DisplayText;
            emit DisplayTextChanged(DisplayText);
        }
    
        void setPage(int Page)
        {
            if (m_Page == Page)
                return;
    
            m_Page = Page;
            emit PageChanged(Page);
        }
    
    
        void setRow(int Row)
        {
            if (m_Row == Row)
                return;
    
            m_Row = Row;
            emit RowChanged(Row);
        }
        void setCol(int Col)
        {
            if (m_Col == Col)
                return;
    
            m_Col = Col;
            emit ColChanged(Col);
        }
    };
    
    typedef QList<Button_model *> ButtonsList;
    

    Page_model.h

    class Page_model : public QAbstractListModel
    {
        Q_OBJECT
    public:
        Page_model(const ButtonsList &buttonList, QObject *parent = NULL)
            : QAbstractListModel(parent), _buttons(buttonList) {}
    
    
        int rowCount(const QModelIndex &parent = QModelIndex()) const;
        QVariant data(const QModelIndex &index, int role) const;
    
        ~Page_model();
    private:
        ButtonsList _buttons;
    };
    
    typedef QList<Page_model *> PagesModelList;
    

    Pages_model.h

    class Pages_model : public QAbstractListModel
    {
        Q_OBJECT
    
    public:
        Pages_model(QObject *parent = NULL);
        Pages_model(const PagesModelList &pageList, QObject *parent = NULL);
        ~Pages_model();
    
        int rowCount(const QModelIndex &parent = QModelIndex()) const;
        QVariant data(const QModelIndex &index, int role) const;
    
        void addAPage(Page_model *pAPageModel);
    private:
        PagesModelList _pagesModelList;
    };
    

    Page.qml

    import QtQuick 2.0
    import QtQuick.Layouts 1.2
    import QtQuick.Window 2.2
    
    Rectangle  {
        width: Screen.width-2
        height: parent.height
        color: transparent
        border.color: "teal"
        border.width: 1
        radius: 3
    
        anchors.horizontalCenter: parent.horizontalCenter
    
        GridLayout {
            id: buttonsContent
            anchors.fill: parent
            margins: 3
    
        }
    }
    

    MainForm.ui.qml

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Layouts 1.2
    
    
    Rectangle {
        id: rectangleMain
    
        property alias buttonView: flickableButtonPages
    
        width: 360
        height: 500
    
        ListView {
            id: flickableButtonPages
            anchors { bottom: parent.bottom;
                      bottomMargin: 86;
                      left: parent.left;
                      leftMargin: 0;
                      right: parent.right
                      rightMargin: 0
                      top: parent.top
                      topMargin: 0
            }
        }
    

    In main.cpp I have:

    QQmlApplicationEngine engine;
    QQmlContext *root_context = engine.rootContext();
    .....
    pagesModel.addAPage(&aPageModel);
    root_context->setContextProperty("myPagesModel",&pagesModel);
    
    P Offline
    P Offline
    p3c0
    Moderators
    wrote on 21 Oct 2015, 06:36 last edited by
    #2

    Hi @TonyN
    Use ``` (3 backticks) instead of @ for code blocks. I have done it for you now.

    157

    1 Reply Last reply
    0
    • T TonyN
      20 Oct 2015, 22:33

      I am quite new to Qt (2 months). Basically I have items that will be displayed in a grid on a page, in a scroll-able view of pages. Most of the examples I found deal with models inside QML. I have items data from a file, thus the models must be from C++ side.
      So far I chose ListView to be my pages scroll view and GridLayout to provide items placement. I chose GridLayout because it allows me to put item anywhere on the grid with extend properties row and column for the items. My models are derived from QAbstractListModel. So far my code is running but does not do anything (obviously). I put some code here, but I think instead try to get my probably "not so right" code to work. Please give me some clue/sample code to work with instead. I still need the UI component to represent item; it can be just a rectangle for now.

      Thanks,

      Button_model.h

      class Button_model : public QObject
      {
          Q_OBJECT
      
          Q_PROPERTY(QString DisplayText READ DisplayText WRITE setDisplayText NOTIFY DisplayTextChanged)
          QString m_DisplayText;
      
          Q_PROPERTY(int Page READ Page WRITE setPage NOTIFY PageChanged)
          int m_Page;
      
          Q_PROPERTY(int Row READ Row WRITE setRow NOTIFY RowChanged)
          int m_Row;
      
          Q_PROPERTY(int Col READ Col WRITE setCol NOTIFY ColChanged)
          int m_Col;
      
      public:
          explicit Button_model(QObject *parent = 0);
      
          QString DisplayText() const
          {
              return m_DisplayText;
          }
      
          int Page() const
          {
              return m_Page;
          }
      
          int Row() const
          {
              return m_Row;
          }
      
          int Col() const
          {
              return m_Col;
          }
      
      signals:
          void DisplayTextChanged(QString DisplayText);
          void PageChanged(int Page);
          void RowChanged(int Row);
          void ColChanged(int Col);
      
      public slots:
          void setDisplayText(QString DisplayText)
          {
              if (m_DisplayText == DisplayText)
                  return;
      
              m_DisplayText = DisplayText;
              emit DisplayTextChanged(DisplayText);
          }
      
          void setPage(int Page)
          {
              if (m_Page == Page)
                  return;
      
              m_Page = Page;
              emit PageChanged(Page);
          }
      
      
          void setRow(int Row)
          {
              if (m_Row == Row)
                  return;
      
              m_Row = Row;
              emit RowChanged(Row);
          }
          void setCol(int Col)
          {
              if (m_Col == Col)
                  return;
      
              m_Col = Col;
              emit ColChanged(Col);
          }
      };
      
      typedef QList<Button_model *> ButtonsList;
      

      Page_model.h

      class Page_model : public QAbstractListModel
      {
          Q_OBJECT
      public:
          Page_model(const ButtonsList &buttonList, QObject *parent = NULL)
              : QAbstractListModel(parent), _buttons(buttonList) {}
      
      
          int rowCount(const QModelIndex &parent = QModelIndex()) const;
          QVariant data(const QModelIndex &index, int role) const;
      
          ~Page_model();
      private:
          ButtonsList _buttons;
      };
      
      typedef QList<Page_model *> PagesModelList;
      

      Pages_model.h

      class Pages_model : public QAbstractListModel
      {
          Q_OBJECT
      
      public:
          Pages_model(QObject *parent = NULL);
          Pages_model(const PagesModelList &pageList, QObject *parent = NULL);
          ~Pages_model();
      
          int rowCount(const QModelIndex &parent = QModelIndex()) const;
          QVariant data(const QModelIndex &index, int role) const;
      
          void addAPage(Page_model *pAPageModel);
      private:
          PagesModelList _pagesModelList;
      };
      

      Page.qml

      import QtQuick 2.0
      import QtQuick.Layouts 1.2
      import QtQuick.Window 2.2
      
      Rectangle  {
          width: Screen.width-2
          height: parent.height
          color: transparent
          border.color: "teal"
          border.width: 1
          radius: 3
      
          anchors.horizontalCenter: parent.horizontalCenter
      
          GridLayout {
              id: buttonsContent
              anchors.fill: parent
              margins: 3
      
          }
      }
      

      MainForm.ui.qml

      import QtQuick 2.4
      import QtQuick.Controls 1.3
      import QtQuick.Layouts 1.2
      
      
      Rectangle {
          id: rectangleMain
      
          property alias buttonView: flickableButtonPages
      
          width: 360
          height: 500
      
          ListView {
              id: flickableButtonPages
              anchors { bottom: parent.bottom;
                        bottomMargin: 86;
                        left: parent.left;
                        leftMargin: 0;
                        right: parent.right
                        rightMargin: 0
                        top: parent.top
                        topMargin: 0
              }
          }
      

      In main.cpp I have:

      QQmlApplicationEngine engine;
      QQmlContext *root_context = engine.rootContext();
      .....
      pagesModel.addAPage(&aPageModel);
      root_context->setContextProperty("myPagesModel",&pagesModel);
      
      P Offline
      P Offline
      p3c0
      Moderators
      wrote on 21 Oct 2015, 06:43 last edited by
      #3

      @TonyN Trying to understand your question. Do you mean you want an example for using C++ models with QML ListView ? A quick look through MainForm.ui.qml shows that you have not assigned the model to ListView.

      157

      1 Reply Last reply
      0
      • T Offline
        T Offline
        TonyN
        wrote on 21 Oct 2015, 13:33 last edited by TonyN
        #4

        Thank you for changing to triple back ticks. I though I saw somewhere in Forum guidelines ask to use @
        I forgot to include main.qml. In there I assign the property alias of buttonView.
        Basically my problem is that I have "lists" inside a "list" (, and individual list of "lists" will bind to GridLayout, not another ListView). That is 2 levels of binding, and my mind just draw a blank, have no idea what to do. I managed to do something like binding to comboBox, text, edit text,... but that straightforward and only at 1 level. So examples, documents, clues, hints,...are appreciated.

        import QtQuick 2.4
        import QtQuick.Window 2.2
        import QtQuick.Extras 1.4
        
        Window {
            visible: true
            visibility: "FullScreen"
            MainForm {
                anchors.fill: parent
                homeButton.onClicked: Qt.quit()
                buttonView.model: myPagesModel
            }
        }
        
        P 1 Reply Last reply 22 Oct 2015, 09:08
        0
        • T TonyN
          21 Oct 2015, 13:33

          Thank you for changing to triple back ticks. I though I saw somewhere in Forum guidelines ask to use @
          I forgot to include main.qml. In there I assign the property alias of buttonView.
          Basically my problem is that I have "lists" inside a "list" (, and individual list of "lists" will bind to GridLayout, not another ListView). That is 2 levels of binding, and my mind just draw a blank, have no idea what to do. I managed to do something like binding to comboBox, text, edit text,... but that straightforward and only at 1 level. So examples, documents, clues, hints,...are appreciated.

          import QtQuick 2.4
          import QtQuick.Window 2.2
          import QtQuick.Extras 1.4
          
          Window {
              visible: true
              visibility: "FullScreen"
              MainForm {
                  anchors.fill: parent
                  homeButton.onClicked: Qt.quit()
                  buttonView.model: myPagesModel
              }
          }
          
          P Offline
          P Offline
          p3c0
          Moderators
          wrote on 22 Oct 2015, 09:08 last edited by
          #5

          @TonyN Why is Pages_model a list ? You can keep it a simple class which can contain another lists.

          157

          T 1 Reply Last reply 22 Oct 2015, 13:30
          0
          • P p3c0
            22 Oct 2015, 09:08

            @TonyN Why is Pages_model a list ? You can keep it a simple class which can contain another lists.

            T Offline
            T Offline
            TonyN
            wrote on 22 Oct 2015, 13:30 last edited by
            #6

            @p3c0 : It's a list because I can have more than 1 page..., and then in each page, I have many items.
            What are you suggesting?

            1 Reply Last reply
            0
            • T TonyN
              20 Oct 2015, 22:33

              I am quite new to Qt (2 months). Basically I have items that will be displayed in a grid on a page, in a scroll-able view of pages. Most of the examples I found deal with models inside QML. I have items data from a file, thus the models must be from C++ side.
              So far I chose ListView to be my pages scroll view and GridLayout to provide items placement. I chose GridLayout because it allows me to put item anywhere on the grid with extend properties row and column for the items. My models are derived from QAbstractListModel. So far my code is running but does not do anything (obviously). I put some code here, but I think instead try to get my probably "not so right" code to work. Please give me some clue/sample code to work with instead. I still need the UI component to represent item; it can be just a rectangle for now.

              Thanks,

              Button_model.h

              class Button_model : public QObject
              {
                  Q_OBJECT
              
                  Q_PROPERTY(QString DisplayText READ DisplayText WRITE setDisplayText NOTIFY DisplayTextChanged)
                  QString m_DisplayText;
              
                  Q_PROPERTY(int Page READ Page WRITE setPage NOTIFY PageChanged)
                  int m_Page;
              
                  Q_PROPERTY(int Row READ Row WRITE setRow NOTIFY RowChanged)
                  int m_Row;
              
                  Q_PROPERTY(int Col READ Col WRITE setCol NOTIFY ColChanged)
                  int m_Col;
              
              public:
                  explicit Button_model(QObject *parent = 0);
              
                  QString DisplayText() const
                  {
                      return m_DisplayText;
                  }
              
                  int Page() const
                  {
                      return m_Page;
                  }
              
                  int Row() const
                  {
                      return m_Row;
                  }
              
                  int Col() const
                  {
                      return m_Col;
                  }
              
              signals:
                  void DisplayTextChanged(QString DisplayText);
                  void PageChanged(int Page);
                  void RowChanged(int Row);
                  void ColChanged(int Col);
              
              public slots:
                  void setDisplayText(QString DisplayText)
                  {
                      if (m_DisplayText == DisplayText)
                          return;
              
                      m_DisplayText = DisplayText;
                      emit DisplayTextChanged(DisplayText);
                  }
              
                  void setPage(int Page)
                  {
                      if (m_Page == Page)
                          return;
              
                      m_Page = Page;
                      emit PageChanged(Page);
                  }
              
              
                  void setRow(int Row)
                  {
                      if (m_Row == Row)
                          return;
              
                      m_Row = Row;
                      emit RowChanged(Row);
                  }
                  void setCol(int Col)
                  {
                      if (m_Col == Col)
                          return;
              
                      m_Col = Col;
                      emit ColChanged(Col);
                  }
              };
              
              typedef QList<Button_model *> ButtonsList;
              

              Page_model.h

              class Page_model : public QAbstractListModel
              {
                  Q_OBJECT
              public:
                  Page_model(const ButtonsList &buttonList, QObject *parent = NULL)
                      : QAbstractListModel(parent), _buttons(buttonList) {}
              
              
                  int rowCount(const QModelIndex &parent = QModelIndex()) const;
                  QVariant data(const QModelIndex &index, int role) const;
              
                  ~Page_model();
              private:
                  ButtonsList _buttons;
              };
              
              typedef QList<Page_model *> PagesModelList;
              

              Pages_model.h

              class Pages_model : public QAbstractListModel
              {
                  Q_OBJECT
              
              public:
                  Pages_model(QObject *parent = NULL);
                  Pages_model(const PagesModelList &pageList, QObject *parent = NULL);
                  ~Pages_model();
              
                  int rowCount(const QModelIndex &parent = QModelIndex()) const;
                  QVariant data(const QModelIndex &index, int role) const;
              
                  void addAPage(Page_model *pAPageModel);
              private:
                  PagesModelList _pagesModelList;
              };
              

              Page.qml

              import QtQuick 2.0
              import QtQuick.Layouts 1.2
              import QtQuick.Window 2.2
              
              Rectangle  {
                  width: Screen.width-2
                  height: parent.height
                  color: transparent
                  border.color: "teal"
                  border.width: 1
                  radius: 3
              
                  anchors.horizontalCenter: parent.horizontalCenter
              
                  GridLayout {
                      id: buttonsContent
                      anchors.fill: parent
                      margins: 3
              
                  }
              }
              

              MainForm.ui.qml

              import QtQuick 2.4
              import QtQuick.Controls 1.3
              import QtQuick.Layouts 1.2
              
              
              Rectangle {
                  id: rectangleMain
              
                  property alias buttonView: flickableButtonPages
              
                  width: 360
                  height: 500
              
                  ListView {
                      id: flickableButtonPages
                      anchors { bottom: parent.bottom;
                                bottomMargin: 86;
                                left: parent.left;
                                leftMargin: 0;
                                right: parent.right
                                rightMargin: 0
                                top: parent.top
                                topMargin: 0
                      }
                  }
              

              In main.cpp I have:

              QQmlApplicationEngine engine;
              QQmlContext *root_context = engine.rootContext();
              .....
              pagesModel.addAPage(&aPageModel);
              root_context->setContextProperty("myPagesModel",&pagesModel);
              
              T Offline
              T Offline
              TonyN
              wrote on 22 Oct 2015, 14:28 last edited by
              #7

              OK, I solved the first level of binding. The application shows pages now.
              In main.cpp, it will have this

              // Simplified code, actual each Page_model has Button_model instances in it
              pagesModel.addPage(new Page_model(&pagesModel));
              pagesModel.addPage(new Page_model(&pagesModel));
              root_context->setContextProperty("myPagesModel",&pagesModel);
              

              In main.qml, I just set the model of the list view
              buttonView.model: myPagesModel
              where buttonView is the property alias of the ListView in main.ui.qml

              property alias buttonView: flickableButtonPages
              
                  ListView {
                      id: flickableButtonPages
                      spacing: 2
                      orientation: ListView.Horizontal
                      flickableDirection: Flickable.HorizontalFlick
                      anchors { bottom: parent.bottom;
                                bottomMargin: 86;
                                left: parent.left;
                                leftMargin: 0;
                                right: parent.right;
                                rightMargin: 0;
                                top: parent.top;
                                topMargin: 0
                      }
              
                      delegate: Page {
                          height: parent.height
                          //width: parent.width
                      }
                  }
              

              The one issue for display is if I set the width of the Page to parent width, as I want to flick 1 page at a time, seems just take down the application with it. But that is a separate question for later.

              Now the main issue (second level of binding) is still remain. How do I bind the items in each page to the GridLayout inside my Page.qml? GridLayout does not even have delegate!

              P 1 Reply Last reply 22 Oct 2015, 15:04
              0
              • T TonyN
                22 Oct 2015, 14:28

                OK, I solved the first level of binding. The application shows pages now.
                In main.cpp, it will have this

                // Simplified code, actual each Page_model has Button_model instances in it
                pagesModel.addPage(new Page_model(&pagesModel));
                pagesModel.addPage(new Page_model(&pagesModel));
                root_context->setContextProperty("myPagesModel",&pagesModel);
                

                In main.qml, I just set the model of the list view
                buttonView.model: myPagesModel
                where buttonView is the property alias of the ListView in main.ui.qml

                property alias buttonView: flickableButtonPages
                
                    ListView {
                        id: flickableButtonPages
                        spacing: 2
                        orientation: ListView.Horizontal
                        flickableDirection: Flickable.HorizontalFlick
                        anchors { bottom: parent.bottom;
                                  bottomMargin: 86;
                                  left: parent.left;
                                  leftMargin: 0;
                                  right: parent.right;
                                  rightMargin: 0;
                                  top: parent.top;
                                  topMargin: 0
                        }
                
                        delegate: Page {
                            height: parent.height
                            //width: parent.width
                        }
                    }
                

                The one issue for display is if I set the width of the Page to parent width, as I want to flick 1 page at a time, seems just take down the application with it. But that is a separate question for later.

                Now the main issue (second level of binding) is still remain. How do I bind the items in each page to the GridLayout inside my Page.qml? GridLayout does not even have delegate!

                P Offline
                P Offline
                p3c0
                Moderators
                wrote on 22 Oct 2015, 15:04 last edited by
                #8

                @TonyN Great news.

                Now the main issue (second level of binding) is still remain. How do I bind the items in each page to the GridLayout inside my Page.qml? GridLayout does not even have delegate!

                GridLayout just manages the positions. I think in your case may be you can use a GridView as it has delegate and model properties or use a Grid with a Repeater inside as it supports model and it can repeat your custom item.

                157

                T 1 Reply Last reply 22 Oct 2015, 15:45
                0
                • P p3c0
                  22 Oct 2015, 15:04

                  @TonyN Great news.

                  Now the main issue (second level of binding) is still remain. How do I bind the items in each page to the GridLayout inside my Page.qml? GridLayout does not even have delegate!

                  GridLayout just manages the positions. I think in your case may be you can use a GridView as it has delegate and model properties or use a Grid with a Repeater inside as it supports model and it can repeat your custom item.

                  T Offline
                  T Offline
                  TonyN
                  wrote on 22 Oct 2015, 15:45 last edited by
                  #9

                  @p3c0 Does GridView support independent row and column for its items like GridLayout?
                  The items that I want to display on a grid-like can be at any row and column, depending on its row and column property. I checked out Grid, GridView, and GridLayout, but it seem only GridLayout allow the attached properties row and column that will allow us to set the item anywhere we want on the grid.

                  P 1 Reply Last reply 22 Oct 2015, 16:07
                  0
                  • T TonyN
                    22 Oct 2015, 15:45

                    @p3c0 Does GridView support independent row and column for its items like GridLayout?
                    The items that I want to display on a grid-like can be at any row and column, depending on its row and column property. I checked out Grid, GridView, and GridLayout, but it seem only GridLayout allow the attached properties row and column that will allow us to set the item anywhere we want on the grid.

                    P Offline
                    P Offline
                    p3c0
                    Moderators
                    wrote on 22 Oct 2015, 16:07 last edited by
                    #10

                    @TonyN Nope they don't unless you add dummy items.

                    157

                    T 1 Reply Last reply 22 Oct 2015, 19:22
                    0
                    • P p3c0
                      22 Oct 2015, 16:07

                      @TonyN Nope they don't unless you add dummy items.

                      T Offline
                      T Offline
                      TonyN
                      wrote on 22 Oct 2015, 19:22 last edited by TonyN
                      #11

                      @p3c0 Well, that's what I guessed.
                      I have an idea. I am not sure it's possible nor how to try to implement it as my knowledge in Qt is very limited. Let look at my Page.qml again

                      import QtQuick 2.0
                      import QtQuick.Layouts 1.2
                      import QtQuick.Window 2.2
                      
                      Rectangle {
                          id: page
                          width: 100
                          height: 180
                          color: "transparent"
                          border.color: "teal"
                          border.width: 1
                          radius: 6
                          GridLayout {
                              id: buttonsLayout
                              columns: 2
                              rows:4
                              anchors { 
                                  rightMargin: 6
                                  leftMargin: 6
                                  bottomMargin: 6
                                  topMargin: 6
                                  fill: parent
                              }
                          }
                      }
                      

                      In here, can we create its own delegate/model property? If we can, maybe a "onModelChanged", I can dynamically add new items to GridLayout (via children property), with their row and column set to Layout.row and Layout.column?

                      P 1 Reply Last reply 23 Oct 2015, 05:35
                      0
                      • T TonyN
                        22 Oct 2015, 19:22

                        @p3c0 Well, that's what I guessed.
                        I have an idea. I am not sure it's possible nor how to try to implement it as my knowledge in Qt is very limited. Let look at my Page.qml again

                        import QtQuick 2.0
                        import QtQuick.Layouts 1.2
                        import QtQuick.Window 2.2
                        
                        Rectangle {
                            id: page
                            width: 100
                            height: 180
                            color: "transparent"
                            border.color: "teal"
                            border.width: 1
                            radius: 6
                            GridLayout {
                                id: buttonsLayout
                                columns: 2
                                rows:4
                                anchors { 
                                    rightMargin: 6
                                    leftMargin: 6
                                    bottomMargin: 6
                                    topMargin: 6
                                    fill: parent
                                }
                            }
                        }
                        

                        In here, can we create its own delegate/model property? If we can, maybe a "onModelChanged", I can dynamically add new items to GridLayout (via children property), with their row and column set to Layout.row and Layout.column?

                        P Offline
                        P Offline
                        p3c0
                        Moderators
                        wrote on 23 Oct 2015, 05:35 last edited by p3c0
                        #12

                        @TonyN I doubt that you can add a delegate and model property for GridLayout. These properties are all inbuilt and have been coded using Qt's C++ API's.
                        Sorry I'm too now unsure what could possibly fulfil your requirement.
                        Try assigning the model to a QtObject like for eg:

                        property QtObject myModel : page_model
                        

                        This will definitely trigger the corresponding handler onMyModelChanged when the page_model will change. You can access the data using myModel object. All the functions defined in the QAbstractItemModel or whatever which page_model inherits will be accessible through myModel.

                        Edited: Please ignore the earlier approach. I have deleted it from here

                        157

                        1 Reply Last reply
                        0
                        • T Offline
                          T Offline
                          TuanLT
                          wrote on 27 Oct 2015, 07:08 last edited by
                          #13

                          Hi TonyN,

                          Can you post your project? I do not understand you.

                          Thanks!

                          1 Reply Last reply
                          0
                          • T TonyN
                            20 Oct 2015, 22:33

                            I am quite new to Qt (2 months). Basically I have items that will be displayed in a grid on a page, in a scroll-able view of pages. Most of the examples I found deal with models inside QML. I have items data from a file, thus the models must be from C++ side.
                            So far I chose ListView to be my pages scroll view and GridLayout to provide items placement. I chose GridLayout because it allows me to put item anywhere on the grid with extend properties row and column for the items. My models are derived from QAbstractListModel. So far my code is running but does not do anything (obviously). I put some code here, but I think instead try to get my probably "not so right" code to work. Please give me some clue/sample code to work with instead. I still need the UI component to represent item; it can be just a rectangle for now.

                            Thanks,

                            Button_model.h

                            class Button_model : public QObject
                            {
                                Q_OBJECT
                            
                                Q_PROPERTY(QString DisplayText READ DisplayText WRITE setDisplayText NOTIFY DisplayTextChanged)
                                QString m_DisplayText;
                            
                                Q_PROPERTY(int Page READ Page WRITE setPage NOTIFY PageChanged)
                                int m_Page;
                            
                                Q_PROPERTY(int Row READ Row WRITE setRow NOTIFY RowChanged)
                                int m_Row;
                            
                                Q_PROPERTY(int Col READ Col WRITE setCol NOTIFY ColChanged)
                                int m_Col;
                            
                            public:
                                explicit Button_model(QObject *parent = 0);
                            
                                QString DisplayText() const
                                {
                                    return m_DisplayText;
                                }
                            
                                int Page() const
                                {
                                    return m_Page;
                                }
                            
                                int Row() const
                                {
                                    return m_Row;
                                }
                            
                                int Col() const
                                {
                                    return m_Col;
                                }
                            
                            signals:
                                void DisplayTextChanged(QString DisplayText);
                                void PageChanged(int Page);
                                void RowChanged(int Row);
                                void ColChanged(int Col);
                            
                            public slots:
                                void setDisplayText(QString DisplayText)
                                {
                                    if (m_DisplayText == DisplayText)
                                        return;
                            
                                    m_DisplayText = DisplayText;
                                    emit DisplayTextChanged(DisplayText);
                                }
                            
                                void setPage(int Page)
                                {
                                    if (m_Page == Page)
                                        return;
                            
                                    m_Page = Page;
                                    emit PageChanged(Page);
                                }
                            
                            
                                void setRow(int Row)
                                {
                                    if (m_Row == Row)
                                        return;
                            
                                    m_Row = Row;
                                    emit RowChanged(Row);
                                }
                                void setCol(int Col)
                                {
                                    if (m_Col == Col)
                                        return;
                            
                                    m_Col = Col;
                                    emit ColChanged(Col);
                                }
                            };
                            
                            typedef QList<Button_model *> ButtonsList;
                            

                            Page_model.h

                            class Page_model : public QAbstractListModel
                            {
                                Q_OBJECT
                            public:
                                Page_model(const ButtonsList &buttonList, QObject *parent = NULL)
                                    : QAbstractListModel(parent), _buttons(buttonList) {}
                            
                            
                                int rowCount(const QModelIndex &parent = QModelIndex()) const;
                                QVariant data(const QModelIndex &index, int role) const;
                            
                                ~Page_model();
                            private:
                                ButtonsList _buttons;
                            };
                            
                            typedef QList<Page_model *> PagesModelList;
                            

                            Pages_model.h

                            class Pages_model : public QAbstractListModel
                            {
                                Q_OBJECT
                            
                            public:
                                Pages_model(QObject *parent = NULL);
                                Pages_model(const PagesModelList &pageList, QObject *parent = NULL);
                                ~Pages_model();
                            
                                int rowCount(const QModelIndex &parent = QModelIndex()) const;
                                QVariant data(const QModelIndex &index, int role) const;
                            
                                void addAPage(Page_model *pAPageModel);
                            private:
                                PagesModelList _pagesModelList;
                            };
                            

                            Page.qml

                            import QtQuick 2.0
                            import QtQuick.Layouts 1.2
                            import QtQuick.Window 2.2
                            
                            Rectangle  {
                                width: Screen.width-2
                                height: parent.height
                                color: transparent
                                border.color: "teal"
                                border.width: 1
                                radius: 3
                            
                                anchors.horizontalCenter: parent.horizontalCenter
                            
                                GridLayout {
                                    id: buttonsContent
                                    anchors.fill: parent
                                    margins: 3
                            
                                }
                            }
                            

                            MainForm.ui.qml

                            import QtQuick 2.4
                            import QtQuick.Controls 1.3
                            import QtQuick.Layouts 1.2
                            
                            
                            Rectangle {
                                id: rectangleMain
                            
                                property alias buttonView: flickableButtonPages
                            
                                width: 360
                                height: 500
                            
                                ListView {
                                    id: flickableButtonPages
                                    anchors { bottom: parent.bottom;
                                              bottomMargin: 86;
                                              left: parent.left;
                                              leftMargin: 0;
                                              right: parent.right
                                              rightMargin: 0
                                              top: parent.top
                                              topMargin: 0
                                    }
                                }
                            

                            In main.cpp I have:

                            QQmlApplicationEngine engine;
                            QQmlContext *root_context = engine.rootContext();
                            .....
                            pagesModel.addAPage(&aPageModel);
                            root_context->setContextProperty("myPagesModel",&pagesModel);
                            
                            T Offline
                            T Offline
                            TonyN
                            wrote on 29 Oct 2015, 14:21 last edited by TonyN
                            #14

                            OK, sorry for not getting back to you guys quickly. I was yanked out to deal with issues of legacy products for past few days!!
                            Let me rephrase my questions again: Basically I want do something like the Android phone or iPhone. We have pages to host the app icons. We flick through the pages to find the app we want, and touch on the icon to run the app. So on my application, I will have pages that contain the items. Items can be different on its look, and when we select an item, we run the action that associated with it.

                            @p3c0, I read through the comments of yours, and modify parts of my code to come up with new project for experiment. I think I have to give up my original idea of GridLayout, and go with GridView with fill in empty items between the items. I use QAbstractTableModel for the GridView. The application still run as the last time it did because I still cannot (don't know how) bind the items of a page to its GridView
                            @TuanLT: here is the whole project

                            Item_Model.h

                            #ifndef ITEM_H
                            #define ITEM_H
                            
                            #include <QObject>
                            
                            class Item_model : public QObject
                            {
                                Q_OBJECT
                            
                                Q_PROPERTY(QString displayText READ displayText WRITE setDisplayText NOTIFY displayTextChanged)
                                QString m_displayText;
                            
                                Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
                                int m_row;
                            
                                Q_PROPERTY(int col READ col WRITE setCol NOTIFY colChanged)
                                int m_col;
                            
                            public:
                                explicit Item_model(QString text = "", int row = 0, int col = 0, QObject *parent = 0);
                            
                                QString displayText() const
                                {
                                    return m_displayText;
                                }
                            
                                int row() const
                                {
                                    return m_row;
                                }
                            
                                int col() const
                                {
                                    return m_col;
                                }
                            
                            signals:
                            
                                void displayTextChanged(QString displayText);
                            
                                void rowChanged(int row);
                            
                                void colChanged(int col);
                            
                            public slots:
                                void setDisplayText(QString displayText)
                                {
                                    if (m_displayText == displayText)
                                        return;
                            
                                    m_displayText = displayText;
                                    emit displayTextChanged(displayText);
                                }
                                void setRow(int row)
                                {
                                    if (m_row == row)
                                        return;
                            
                                    m_row = row;
                                    emit rowChanged(row);
                                }
                                void setCol(int col)
                                {
                                    if (m_col == col)
                                        return;
                            
                                    m_col = col;
                                    emit colChanged(col);
                                }
                            };
                            
                            typedef QList<Item_model *> ItemsList;
                            #endif // ITEM_H
                            

                            Item_model.cpp

                            #include "Item_model.h"
                            
                            Item_model::Item_model(QString text, int row, int col, QObject *parent) : QObject(parent)
                            {
                                m_row = row;
                                m_col = col;
                                m_displayText = text;
                            }
                            

                            Items_model.h

                            #ifndef ITEMS_MODEL_H
                            #define ITEMS_MODEL_H
                            
                            #include <QtCore/QAbstractTableModel>
                            #include "Item_model.h"
                            
                            class Items_model : public QAbstractTableModel
                            {
                                Q_OBJECT
                            public:
                                Items_model(int maxRow, int maxColumns, QObject *parent = NULL);
                            
                                int rowCount(const QModelIndex &parent = QModelIndex()) const;
                                int columnCount(const QModelIndex & parent = QModelIndex()) const;
                                QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
                            
                                void addItem(Item_model *pItem);
                            private:
                                ItemsList _itemsList;
                                int _maxRows;
                                int _maxCols;
                            };
                            
                            #endif // ITEMS_MODEL_H
                            

                            Items_model.cpp

                            #include "Items_model.h"

                            Items_model::Items_model(int maxRow, int maxColumns, QObject *parent)
                                :QAbstractTableModel(parent)
                            {
                                _maxCols = maxColumns;
                                _maxRows = maxRow;
                            }
                            
                            int Items_model::rowCount(const QModelIndex &parent) const
                            {
                                return _maxRows;
                            }
                            
                            int Items_model::columnCount(const QModelIndex & parent) const
                            {
                                return _maxCols;
                            }
                            
                            QVariant Items_model::data(const QModelIndex &index, int role) const
                            {
                                if (!index.isValid())
                                    return QVariant();
                            
                                int indexRow = index.row();
                                int indexCol = index.column();
                                if (indexRow >= _maxRows || indexCol >= _maxCols)
                                    return QVariant();
                            
                                if (role == Qt::DisplayRole)
                                {
                                    foreach(Item_model *pItem, _itemsList )
                                    {
                                        if (pItem->row() == indexRow &&  pItem->col() == indexCol)
                                        {
                                            return pItem->displayText();
                                        }
                                    }
                                }
                            
                                return QVariant();
                            }
                            
                            void Items_model::addItem(Item_model *pItem)
                            {
                                //
                                // Need check for row and column before append
                                //
                                _itemsList.append(pItem);
                            }
                            

                            Page_model.h

                            #ifndef PAGE_MODEL_H
                            #define PAGE_MODEL_H
                            
                            #include <QtCore/QObject>
                            #include "Items_model.h"
                            
                            class Page_model : public QObject
                            {
                                Q_OBJECT
                                Q_PROPERTY(Items_model* Items READ Items WRITE setItems NOTIFY ItemsChanged)
                                Items_model* m_Items;
                            
                            public:
                                explicit Page_model(QObject *parent = 0);
                            
                            Items_model* Items() const
                            {
                                return m_Items;
                            }
                            
                            signals:
                            
                            void ItemsChanged(Items_model* Items);
                            
                            public slots:
                            void setItems(Items_model* Items)
                            {
                                if (m_Items == Items)
                                    return;
                            
                                m_Items = Items;
                                emit ItemsChanged(Items);
                            }
                            };
                            typedef QList<Page_model *> PagesModelList;
                            #endif // PAGE_MODEL_H
                            

                            Page_model.cpp

                            #include "Page_model.h"
                            
                            Page_model::Page_model(QObject *parent) : QObject(parent)
                            {
                                m_Items = new Items_model(5,4,this);
                            }
                            

                            Pages_model.h

                            #ifndef PAGES_MODEL_H
                            #define PAGES_MODEL_H
                            
                            #include "Page_model.h"
                            
                            class Pages_model : public QAbstractListModel
                            {
                                Q_OBJECT
                            public:
                                Pages_model();
                                int rowCount(const QModelIndex &parent = QModelIndex()) const;
                                QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
                            
                                void addPage(Page_model *pPageModel);
                            private:
                                PagesModelList _pagesModelList;
                            };
                            
                            #endif // PAGES_MODEL_H
                            

                            Pages_model.cpp

                            #include "Pages_model.h"
                            
                            Pages_model::Pages_model()
                            {
                            
                            }
                            int Pages_model::rowCount(const QModelIndex &parent) const
                            {
                                return _pagesModelList.count();
                            }
                            
                            QVariant Pages_model::data(const QModelIndex &index, int role) const
                            {
                                if (!index.isValid())
                                    return QVariant();
                            
                                int i = index.row();
                                if (i >= _pagesModelList.count())
                                    return QVariant();
                            
                                return QVariant::fromValue(_pagesModelList[i]);
                            }
                            
                            void Pages_model::addPage(Page_model *pPageModel)
                            {
                                _pagesModelList.append(pPageModel);
                            }
                            

                            main.cpp

                            #include <QGuiApplication>
                            #include <QQmlApplicationEngine>
                            #include <QQmlContext>
                            #include <QtQml>
                            
                            #include "Pages_model.h"
                            
                            int main(int argc, char *argv[])
                            {
                                QGuiApplication app(argc, argv);
                            
                                QQmlApplicationEngine engine;
                            
                                QQmlContext *root_context = engine.rootContext();
                            
                                //
                                // prepare test data
                                //
                                Pages_model pagesModel;
                                Page_model page1(&pagesModel);
                                Page_model page2(&pagesModel);
                                Page_model page3(&pagesModel);
                            
                                page1.Items()->addItem(new Item_model("Page 1, R2, C3", 2, 3, &page1));
                                page1.Items()->addItem(new Item_model("Page 1, R0, C0", 0, 0, &page1));
                                page1.Items()->addItem(new Item_model("Page 1, R1, C2", 0, 2, &page1));
                            
                                page2.Items()->addItem(new Item_model("Page 2, R2, C3", 2, 3, &page2));
                                page2.Items()->addItem(new Item_model("Page 2, R0, C0", 0, 0, &page2));
                            
                                page3.Items()->addItem(new Item_model("Page 3, R3, C3", 3, 3, &page1));
                                page3.Items()->addItem(new Item_model("Page 3, R0, C4", 0, 4, &page1));
                                page3.Items()->addItem(new Item_model("Page 3, R1, C2", 0, 2, &page1));
                            
                            
                                pagesModel.addPage(&page1);
                                pagesModel.addPage(&page2);
                                pagesModel.addPage(&page3);
                                root_context->setContextProperty("myPagesModel",&pagesModel);
                                //
                                // load the main page
                                //
                                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                            
                                return app.exec();
                            }
                            

                            main.qml

                            import QtQuick 2.4
                            import QtQuick.Window 2.2
                            
                            Window {
                                visible: true
                                MainForm {
                                    anchors.fill: parent
                                    quitButton.onClicked: {
                                        Qt.quit();
                                    }
                            
                                    pagesView.model: myPagesModel
                            
                                }
                            }
                            

                            MainForm.ui.qml

                            import QtQuick 2.4
                            import QtQuick.Controls 1.3
                            
                            Rectangle {
                                id: rectangleMain
                                property alias quitButton: quitButton
                                property alias pagesView: pagesView
                            
                                width: 360
                                height: 360
                            
                            
                            
                            
                                ListView {
                                    id: pagesView
                                    width: 500
                                    orientation: ListView.Horizontal
                                    spacing: 2
                            
                                    anchors.bottom: quitButton.top
                                    anchors.bottomMargin: 8
                                    anchors.right: parent.right
                                    anchors.rightMargin: 0
                                    anchors.left: parent.left
                                    anchors.leftMargin: 0
                                    anchors.top: parent.top
                                    anchors.topMargin: 0
                            
                                    delegate: PageView {
                                        height: parent.height
                                        viewModel: model.Items
                                        //displayItems:parent.model.Items
                            
                                    }
                                }
                            
                                Button {
                                    id: quitButton
                                    y: 325
                                    text: qsTr("Quit")
                                    anchors.right: parent.right
                                    anchors.rightMargin: 50
                                    anchors.left: parent.left
                                    anchors.leftMargin: 50
                                    anchors.bottom: parent.bottom
                                    anchors.bottomMargin: 8
                                }
                            }
                            

                            PageView.qml

                            import QtQuick 2.0
                            import QtQuick.Layouts 1.2
                            import QtQuick.Window 2.2
                            
                            Rectangle {
                                property alias viewModel:gridViewItems.model
                            
                                id: pageView
                                width: 100
                                height: 180
                                color: "transparent"
                                border.color: "teal"
                                border.width: 1
                                radius: 6
                            
                                GridView {
                                    id: gridViewItems
                                    anchors { rightMargin: 6
                                        leftMargin: 6
                                        bottomMargin: 6
                                        topMargin: 6
                                        fill: parent
                                    }
                                    cellWidth: width / 2
                                    cellHeight: 50
                            
                                    delegate: ItemView {
                                        height: 46
                                        width: 46
                                        color: "blue" //colorCode
                                        displayText:"hello"//name
                                    }
                            
                            //        model: ListModel {
                            //            ListElement {
                            //                name: "Grey"
                            //                colorCode: "grey"
                            //            }
                            
                            //            ListElement {
                            //                name: "Red"
                            //                colorCode: "red"
                            //            }
                            
                            //            ListElement {
                            //                name: "Blue"
                            //                colorCode: "blue"
                            //            }
                            
                            //            ListElement {
                            //                name: "Green"
                            //                colorCode: "green"
                            //            }
                            //        }
                                }
                            }
                            

                            ItemView.qml

                            import QtQuick 2.0
                            
                            Rectangle {
                                property alias displayText: displayText.text
                                width: 100
                                height: 62
                                Text {
                                    id: displayText
                                    anchors.horizontalCenter: parent.horizontalCenter
                                    anchors.verticalCenter: parent.verticalCenter
                                }
                            }
                            
                            T 1 Reply Last reply 29 Oct 2015, 22:16
                            0
                            • T TonyN
                              29 Oct 2015, 14:21

                              OK, sorry for not getting back to you guys quickly. I was yanked out to deal with issues of legacy products for past few days!!
                              Let me rephrase my questions again: Basically I want do something like the Android phone or iPhone. We have pages to host the app icons. We flick through the pages to find the app we want, and touch on the icon to run the app. So on my application, I will have pages that contain the items. Items can be different on its look, and when we select an item, we run the action that associated with it.

                              @p3c0, I read through the comments of yours, and modify parts of my code to come up with new project for experiment. I think I have to give up my original idea of GridLayout, and go with GridView with fill in empty items between the items. I use QAbstractTableModel for the GridView. The application still run as the last time it did because I still cannot (don't know how) bind the items of a page to its GridView
                              @TuanLT: here is the whole project

                              Item_Model.h

                              #ifndef ITEM_H
                              #define ITEM_H
                              
                              #include <QObject>
                              
                              class Item_model : public QObject
                              {
                                  Q_OBJECT
                              
                                  Q_PROPERTY(QString displayText READ displayText WRITE setDisplayText NOTIFY displayTextChanged)
                                  QString m_displayText;
                              
                                  Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged)
                                  int m_row;
                              
                                  Q_PROPERTY(int col READ col WRITE setCol NOTIFY colChanged)
                                  int m_col;
                              
                              public:
                                  explicit Item_model(QString text = "", int row = 0, int col = 0, QObject *parent = 0);
                              
                                  QString displayText() const
                                  {
                                      return m_displayText;
                                  }
                              
                                  int row() const
                                  {
                                      return m_row;
                                  }
                              
                                  int col() const
                                  {
                                      return m_col;
                                  }
                              
                              signals:
                              
                                  void displayTextChanged(QString displayText);
                              
                                  void rowChanged(int row);
                              
                                  void colChanged(int col);
                              
                              public slots:
                                  void setDisplayText(QString displayText)
                                  {
                                      if (m_displayText == displayText)
                                          return;
                              
                                      m_displayText = displayText;
                                      emit displayTextChanged(displayText);
                                  }
                                  void setRow(int row)
                                  {
                                      if (m_row == row)
                                          return;
                              
                                      m_row = row;
                                      emit rowChanged(row);
                                  }
                                  void setCol(int col)
                                  {
                                      if (m_col == col)
                                          return;
                              
                                      m_col = col;
                                      emit colChanged(col);
                                  }
                              };
                              
                              typedef QList<Item_model *> ItemsList;
                              #endif // ITEM_H
                              

                              Item_model.cpp

                              #include "Item_model.h"
                              
                              Item_model::Item_model(QString text, int row, int col, QObject *parent) : QObject(parent)
                              {
                                  m_row = row;
                                  m_col = col;
                                  m_displayText = text;
                              }
                              

                              Items_model.h

                              #ifndef ITEMS_MODEL_H
                              #define ITEMS_MODEL_H
                              
                              #include <QtCore/QAbstractTableModel>
                              #include "Item_model.h"
                              
                              class Items_model : public QAbstractTableModel
                              {
                                  Q_OBJECT
                              public:
                                  Items_model(int maxRow, int maxColumns, QObject *parent = NULL);
                              
                                  int rowCount(const QModelIndex &parent = QModelIndex()) const;
                                  int columnCount(const QModelIndex & parent = QModelIndex()) const;
                                  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
                              
                                  void addItem(Item_model *pItem);
                              private:
                                  ItemsList _itemsList;
                                  int _maxRows;
                                  int _maxCols;
                              };
                              
                              #endif // ITEMS_MODEL_H
                              

                              Items_model.cpp

                              #include "Items_model.h"

                              Items_model::Items_model(int maxRow, int maxColumns, QObject *parent)
                                  :QAbstractTableModel(parent)
                              {
                                  _maxCols = maxColumns;
                                  _maxRows = maxRow;
                              }
                              
                              int Items_model::rowCount(const QModelIndex &parent) const
                              {
                                  return _maxRows;
                              }
                              
                              int Items_model::columnCount(const QModelIndex & parent) const
                              {
                                  return _maxCols;
                              }
                              
                              QVariant Items_model::data(const QModelIndex &index, int role) const
                              {
                                  if (!index.isValid())
                                      return QVariant();
                              
                                  int indexRow = index.row();
                                  int indexCol = index.column();
                                  if (indexRow >= _maxRows || indexCol >= _maxCols)
                                      return QVariant();
                              
                                  if (role == Qt::DisplayRole)
                                  {
                                      foreach(Item_model *pItem, _itemsList )
                                      {
                                          if (pItem->row() == indexRow &&  pItem->col() == indexCol)
                                          {
                                              return pItem->displayText();
                                          }
                                      }
                                  }
                              
                                  return QVariant();
                              }
                              
                              void Items_model::addItem(Item_model *pItem)
                              {
                                  //
                                  // Need check for row and column before append
                                  //
                                  _itemsList.append(pItem);
                              }
                              

                              Page_model.h

                              #ifndef PAGE_MODEL_H
                              #define PAGE_MODEL_H
                              
                              #include <QtCore/QObject>
                              #include "Items_model.h"
                              
                              class Page_model : public QObject
                              {
                                  Q_OBJECT
                                  Q_PROPERTY(Items_model* Items READ Items WRITE setItems NOTIFY ItemsChanged)
                                  Items_model* m_Items;
                              
                              public:
                                  explicit Page_model(QObject *parent = 0);
                              
                              Items_model* Items() const
                              {
                                  return m_Items;
                              }
                              
                              signals:
                              
                              void ItemsChanged(Items_model* Items);
                              
                              public slots:
                              void setItems(Items_model* Items)
                              {
                                  if (m_Items == Items)
                                      return;
                              
                                  m_Items = Items;
                                  emit ItemsChanged(Items);
                              }
                              };
                              typedef QList<Page_model *> PagesModelList;
                              #endif // PAGE_MODEL_H
                              

                              Page_model.cpp

                              #include "Page_model.h"
                              
                              Page_model::Page_model(QObject *parent) : QObject(parent)
                              {
                                  m_Items = new Items_model(5,4,this);
                              }
                              

                              Pages_model.h

                              #ifndef PAGES_MODEL_H
                              #define PAGES_MODEL_H
                              
                              #include "Page_model.h"
                              
                              class Pages_model : public QAbstractListModel
                              {
                                  Q_OBJECT
                              public:
                                  Pages_model();
                                  int rowCount(const QModelIndex &parent = QModelIndex()) const;
                                  QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
                              
                                  void addPage(Page_model *pPageModel);
                              private:
                                  PagesModelList _pagesModelList;
                              };
                              
                              #endif // PAGES_MODEL_H
                              

                              Pages_model.cpp

                              #include "Pages_model.h"
                              
                              Pages_model::Pages_model()
                              {
                              
                              }
                              int Pages_model::rowCount(const QModelIndex &parent) const
                              {
                                  return _pagesModelList.count();
                              }
                              
                              QVariant Pages_model::data(const QModelIndex &index, int role) const
                              {
                                  if (!index.isValid())
                                      return QVariant();
                              
                                  int i = index.row();
                                  if (i >= _pagesModelList.count())
                                      return QVariant();
                              
                                  return QVariant::fromValue(_pagesModelList[i]);
                              }
                              
                              void Pages_model::addPage(Page_model *pPageModel)
                              {
                                  _pagesModelList.append(pPageModel);
                              }
                              

                              main.cpp

                              #include <QGuiApplication>
                              #include <QQmlApplicationEngine>
                              #include <QQmlContext>
                              #include <QtQml>
                              
                              #include "Pages_model.h"
                              
                              int main(int argc, char *argv[])
                              {
                                  QGuiApplication app(argc, argv);
                              
                                  QQmlApplicationEngine engine;
                              
                                  QQmlContext *root_context = engine.rootContext();
                              
                                  //
                                  // prepare test data
                                  //
                                  Pages_model pagesModel;
                                  Page_model page1(&pagesModel);
                                  Page_model page2(&pagesModel);
                                  Page_model page3(&pagesModel);
                              
                                  page1.Items()->addItem(new Item_model("Page 1, R2, C3", 2, 3, &page1));
                                  page1.Items()->addItem(new Item_model("Page 1, R0, C0", 0, 0, &page1));
                                  page1.Items()->addItem(new Item_model("Page 1, R1, C2", 0, 2, &page1));
                              
                                  page2.Items()->addItem(new Item_model("Page 2, R2, C3", 2, 3, &page2));
                                  page2.Items()->addItem(new Item_model("Page 2, R0, C0", 0, 0, &page2));
                              
                                  page3.Items()->addItem(new Item_model("Page 3, R3, C3", 3, 3, &page1));
                                  page3.Items()->addItem(new Item_model("Page 3, R0, C4", 0, 4, &page1));
                                  page3.Items()->addItem(new Item_model("Page 3, R1, C2", 0, 2, &page1));
                              
                              
                                  pagesModel.addPage(&page1);
                                  pagesModel.addPage(&page2);
                                  pagesModel.addPage(&page3);
                                  root_context->setContextProperty("myPagesModel",&pagesModel);
                                  //
                                  // load the main page
                                  //
                                  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                              
                                  return app.exec();
                              }
                              

                              main.qml

                              import QtQuick 2.4
                              import QtQuick.Window 2.2
                              
                              Window {
                                  visible: true
                                  MainForm {
                                      anchors.fill: parent
                                      quitButton.onClicked: {
                                          Qt.quit();
                                      }
                              
                                      pagesView.model: myPagesModel
                              
                                  }
                              }
                              

                              MainForm.ui.qml

                              import QtQuick 2.4
                              import QtQuick.Controls 1.3
                              
                              Rectangle {
                                  id: rectangleMain
                                  property alias quitButton: quitButton
                                  property alias pagesView: pagesView
                              
                                  width: 360
                                  height: 360
                              
                              
                              
                              
                                  ListView {
                                      id: pagesView
                                      width: 500
                                      orientation: ListView.Horizontal
                                      spacing: 2
                              
                                      anchors.bottom: quitButton.top
                                      anchors.bottomMargin: 8
                                      anchors.right: parent.right
                                      anchors.rightMargin: 0
                                      anchors.left: parent.left
                                      anchors.leftMargin: 0
                                      anchors.top: parent.top
                                      anchors.topMargin: 0
                              
                                      delegate: PageView {
                                          height: parent.height
                                          viewModel: model.Items
                                          //displayItems:parent.model.Items
                              
                                      }
                                  }
                              
                                  Button {
                                      id: quitButton
                                      y: 325
                                      text: qsTr("Quit")
                                      anchors.right: parent.right
                                      anchors.rightMargin: 50
                                      anchors.left: parent.left
                                      anchors.leftMargin: 50
                                      anchors.bottom: parent.bottom
                                      anchors.bottomMargin: 8
                                  }
                              }
                              

                              PageView.qml

                              import QtQuick 2.0
                              import QtQuick.Layouts 1.2
                              import QtQuick.Window 2.2
                              
                              Rectangle {
                                  property alias viewModel:gridViewItems.model
                              
                                  id: pageView
                                  width: 100
                                  height: 180
                                  color: "transparent"
                                  border.color: "teal"
                                  border.width: 1
                                  radius: 6
                              
                                  GridView {
                                      id: gridViewItems
                                      anchors { rightMargin: 6
                                          leftMargin: 6
                                          bottomMargin: 6
                                          topMargin: 6
                                          fill: parent
                                      }
                                      cellWidth: width / 2
                                      cellHeight: 50
                              
                                      delegate: ItemView {
                                          height: 46
                                          width: 46
                                          color: "blue" //colorCode
                                          displayText:"hello"//name
                                      }
                              
                              //        model: ListModel {
                              //            ListElement {
                              //                name: "Grey"
                              //                colorCode: "grey"
                              //            }
                              
                              //            ListElement {
                              //                name: "Red"
                              //                colorCode: "red"
                              //            }
                              
                              //            ListElement {
                              //                name: "Blue"
                              //                colorCode: "blue"
                              //            }
                              
                              //            ListElement {
                              //                name: "Green"
                              //                colorCode: "green"
                              //            }
                              //        }
                                  }
                              }
                              

                              ItemView.qml

                              import QtQuick 2.0
                              
                              Rectangle {
                                  property alias displayText: displayText.text
                                  width: 100
                                  height: 62
                                  Text {
                                      id: displayText
                                      anchors.horizontalCenter: parent.horizontalCenter
                                      anchors.verticalCenter: parent.verticalCenter
                                  }
                              }
                              
                              T Offline
                              T Offline
                              TonyN
                              wrote on 29 Oct 2015, 22:16 last edited by
                              #15

                              I simplified the MainForm.ui.qml (as below) and find that the QML report "TypeError: Cannot read property 'items' of undefined" for each instance of the the page when I execute the app. According to this, I think I have to register Items_model. However I am unable to do so with qmlRegisterType()

                              (I rename the property Items in Page_model to have lowercamel: Q_PROPERTY(Items_model* items READ Items WRITE setItems NOTIFY itemsChanged) )

                              import QtQuick 2.4
                              import QtQuick.Controls 1.3
                              
                              Rectangle {
                                  id: rectangleMain
                                  property alias quitButton: quitButton
                                  property alias pagesView: pagesView
                              
                                  width: 360
                                  height: 360
                              
                              
                              
                              
                                  ListView {
                                      id: pagesView
                                      width: 500
                                      orientation: ListView.Horizontal
                                      spacing: 2
                              
                                      anchors {
                                          bottom: quitButton.top
                                          bottomMargin: 8
                                          right: parent.right
                                          rightMargin: 0
                                          left: parent.left
                                          leftMargin: 0
                                          top: parent.top
                                          topMargin: 0
                                      }
                              
                                      delegate: Rectangle {
                                          id:paView
                                          height: parent.height
                                          width:100
                                          color: "transparent"
                                          border.color: "teal"
                                          border.width: 1
                                          radius: 6
                              
                                          GridView {
                              
                                              anchors { rightMargin: 6
                                                  leftMargin: 6
                                                  bottomMargin: 6
                                                  topMargin: 6
                                                  fill: parent
                                              }
                                              cellWidth: width / 2
                                              cellHeight: 50
                              
                                              model:model.items
                              
                                              delegate: Rectangle {
                                                  height: 46
                                                  width: 46
                                                  color: "blue" //colorCode
                                                  Text {
                              
                                                      anchors.horizontalCenter: parent.horizontalCenter
                                                      anchors.verticalCenter: parent.verticalCenter
                                                      text:model.displayText
                                                  }
                                              }
                                          }
                                      }
                                  }
                              
                                  Button {
                                      id: quitButton
                                      y: 325
                                      text: qsTr("Quit")
                                      anchors {
                                          right: parent.right
                                          rightMargin: 50
                                          left: parent.left
                                          leftMargin: 50
                                          bottom: parent.bottom
                                          bottomMargin: 8
                                      }
                                  }
                              }
                              
                              P 1 Reply Last reply 31 Oct 2015, 11:22
                              0
                              • T Offline
                                T Offline
                                TuanLT
                                wrote on 30 Oct 2015, 02:47 last edited by
                                #16

                                Thanks you very much!

                                But, now i have new problem, when i using signal and slot to communicate between cpp file and qml file. I'm using code below:

                                Cpp file (main.cpp)

                                QQmlApplicationEngine engine;
                                QQmlContext* context = engine.rootContext();
                                engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                                QObject *topLevel = engine.rootObjects().value(0);
                                QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
                                KeywordBusiness business;
                                QObject::connect(window,SIGNAL(savekeywords(KeywordsModel)), &business, SLOT(SaveChangedData(KeywordsModel)));

                                on class KeywordBusiness .h I define a slot SaveChangedData with parameter is KeywordsModel extends QObject

                                On qml file. I define a signal savekeywords with also parameter is KeywordsModel.

                                But when i click button to call signal savekeywords , in cpp file the QObject::connect funtion not working.

                                Please help me, I was missing something?

                                Thanks!

                                T 1 Reply Last reply 30 Oct 2015, 17:38
                                0
                                • T TuanLT
                                  30 Oct 2015, 02:47

                                  Thanks you very much!

                                  But, now i have new problem, when i using signal and slot to communicate between cpp file and qml file. I'm using code below:

                                  Cpp file (main.cpp)

                                  QQmlApplicationEngine engine;
                                  QQmlContext* context = engine.rootContext();
                                  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                                  QObject *topLevel = engine.rootObjects().value(0);
                                  QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
                                  KeywordBusiness business;
                                  QObject::connect(window,SIGNAL(savekeywords(KeywordsModel)), &business, SLOT(SaveChangedData(KeywordsModel)));

                                  on class KeywordBusiness .h I define a slot SaveChangedData with parameter is KeywordsModel extends QObject

                                  On qml file. I define a signal savekeywords with also parameter is KeywordsModel.

                                  But when i click button to call signal savekeywords , in cpp file the QObject::connect funtion not working.

                                  Please help me, I was missing something?

                                  Thanks!

                                  T Offline
                                  T Offline
                                  TonyN
                                  wrote on 30 Oct 2015, 17:38 last edited by
                                  #17

                                  @TuanLT Dude, I post it for someone to help me to solve my problem. Please post your question in the separate post.

                                  1 Reply Last reply
                                  0
                                  • T TonyN
                                    29 Oct 2015, 22:16

                                    I simplified the MainForm.ui.qml (as below) and find that the QML report "TypeError: Cannot read property 'items' of undefined" for each instance of the the page when I execute the app. According to this, I think I have to register Items_model. However I am unable to do so with qmlRegisterType()

                                    (I rename the property Items in Page_model to have lowercamel: Q_PROPERTY(Items_model* items READ Items WRITE setItems NOTIFY itemsChanged) )

                                    import QtQuick 2.4
                                    import QtQuick.Controls 1.3
                                    
                                    Rectangle {
                                        id: rectangleMain
                                        property alias quitButton: quitButton
                                        property alias pagesView: pagesView
                                    
                                        width: 360
                                        height: 360
                                    
                                    
                                    
                                    
                                        ListView {
                                            id: pagesView
                                            width: 500
                                            orientation: ListView.Horizontal
                                            spacing: 2
                                    
                                            anchors {
                                                bottom: quitButton.top
                                                bottomMargin: 8
                                                right: parent.right
                                                rightMargin: 0
                                                left: parent.left
                                                leftMargin: 0
                                                top: parent.top
                                                topMargin: 0
                                            }
                                    
                                            delegate: Rectangle {
                                                id:paView
                                                height: parent.height
                                                width:100
                                                color: "transparent"
                                                border.color: "teal"
                                                border.width: 1
                                                radius: 6
                                    
                                                GridView {
                                    
                                                    anchors { rightMargin: 6
                                                        leftMargin: 6
                                                        bottomMargin: 6
                                                        topMargin: 6
                                                        fill: parent
                                                    }
                                                    cellWidth: width / 2
                                                    cellHeight: 50
                                    
                                                    model:model.items
                                    
                                                    delegate: Rectangle {
                                                        height: 46
                                                        width: 46
                                                        color: "blue" //colorCode
                                                        Text {
                                    
                                                            anchors.horizontalCenter: parent.horizontalCenter
                                                            anchors.verticalCenter: parent.verticalCenter
                                                            text:model.displayText
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    
                                        Button {
                                            id: quitButton
                                            y: 325
                                            text: qsTr("Quit")
                                            anchors {
                                                right: parent.right
                                                rightMargin: 50
                                                left: parent.left
                                                leftMargin: 50
                                                bottom: parent.bottom
                                                bottomMargin: 8
                                            }
                                        }
                                    }
                                    
                                    P Offline
                                    P Offline
                                    p3c0
                                    Moderators
                                    wrote on 31 Oct 2015, 11:22 last edited by
                                    #18

                                    @TonyN

                                    I simplified the MainForm.ui.qml (as below) and find that the QML report "TypeError: Cannot read property 'items' of undefined" for each instance of the the page when I execute the app.

                                    Since that property is in parent model try accessing it with its parent object.
                                    model: pagesView.model.items

                                    157

                                    T 1 Reply Last reply 2 Nov 2015, 16:04
                                    0
                                    • P p3c0
                                      31 Oct 2015, 11:22

                                      @TonyN

                                      I simplified the MainForm.ui.qml (as below) and find that the QML report "TypeError: Cannot read property 'items' of undefined" for each instance of the the page when I execute the app.

                                      Since that property is in parent model try accessing it with its parent object.
                                      model: pagesView.model.items

                                      T Offline
                                      T Offline
                                      TonyN
                                      wrote on 2 Nov 2015, 16:04 last edited by
                                      #19

                                      @p3c0 : Thanks, you are correct about that, but that is not enough to solve the problem. I find out what was missing. Instead, create the Q_PROPERTY, I have to create custom "roles" like these (example code below) in the model. Again, I don't know this is the right way or not, but it solved my problem of binding models further down on the chain (second level). But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!

                                      QHash<int, QByteArray> Pages_model::roleNames() const
                                      {
                                          QHash<int, QByteArray> roles;
                                          roles[DisplayNameRole] = "displayName";
                                          roles[DisplayItemsRole] = "displayItems";
                                      
                                          return roles;
                                      }
                                      
                                      QVariant Pages_model::data(const QModelIndex &index, int role) const
                                      {
                                          if (!index.isValid())
                                              return QVariant();
                                      
                                          int i = index.row();
                                          if (i < 0 || i >= _pagesModelList.count())
                                              return QVariant();
                                      
                                          const Page_model *pPage = _pagesModelList[i];
                                          if (role == DisplayNameRole)
                                          {
                                              return pPage->displayName();
                                          }
                                          else if (role == DisplayItemsRole)
                                          {
                                              return QVariant::fromValue(pPage->Items());
                                          }
                                      
                                          return QVariant();
                                      }
                                      
                                      P 1 Reply Last reply 3 Nov 2015, 09:53
                                      0
                                      • T TonyN
                                        2 Nov 2015, 16:04

                                        @p3c0 : Thanks, you are correct about that, but that is not enough to solve the problem. I find out what was missing. Instead, create the Q_PROPERTY, I have to create custom "roles" like these (example code below) in the model. Again, I don't know this is the right way or not, but it solved my problem of binding models further down on the chain (second level). But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!

                                        QHash<int, QByteArray> Pages_model::roleNames() const
                                        {
                                            QHash<int, QByteArray> roles;
                                            roles[DisplayNameRole] = "displayName";
                                            roles[DisplayItemsRole] = "displayItems";
                                        
                                            return roles;
                                        }
                                        
                                        QVariant Pages_model::data(const QModelIndex &index, int role) const
                                        {
                                            if (!index.isValid())
                                                return QVariant();
                                        
                                            int i = index.row();
                                            if (i < 0 || i >= _pagesModelList.count())
                                                return QVariant();
                                        
                                            const Page_model *pPage = _pagesModelList[i];
                                            if (role == DisplayNameRole)
                                            {
                                                return pPage->displayName();
                                            }
                                            else if (role == DisplayItemsRole)
                                            {
                                                return QVariant::fromValue(pPage->Items());
                                            }
                                        
                                            return QVariant();
                                        }
                                        
                                        P Offline
                                        P Offline
                                        p3c0
                                        Moderators
                                        wrote on 3 Nov 2015, 09:53 last edited by
                                        #20

                                        @TonyN

                                        But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!

                                        That's right GridView or ListView only deals with rows. In that case can't you replace it with QAbstractItemModel ? Keep everything other than columns.

                                        157

                                        T 2 Replies Last reply 3 Nov 2015, 15:49
                                        0
                                        • P p3c0
                                          3 Nov 2015, 09:53

                                          @TonyN

                                          But then now, I find out that the QAbstractTableModel may not the right choice :~) Despite I implemented columnCount(), it only ask for data in rows of column 0!!

                                          That's right GridView or ListView only deals with rows. In that case can't you replace it with QAbstractItemModel ? Keep everything other than columns.

                                          T Offline
                                          T Offline
                                          TonyN
                                          wrote on 3 Nov 2015, 15:49 last edited by
                                          #21

                                          @p3c0 Uh but then which view should I use? I read this,
                                          "QAbstractItemModel presents a hierarchy of tables, but the views currently provided by QML can only display list data."
                                          Does that mean, at the present time, nothing I can use except maybe create my own view!? If so, what is the best reading can you recommend?

                                          1 Reply Last reply
                                          0

                                          11/25

                                          22 Oct 2015, 19:22

                                          • Login

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