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

Binding list from C++ to QML

Scheduled Pinned Locked Moved Solved QML and Qt Quick
qml binding
25 Posts 3 Posters 13.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • 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
                    • 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, 23:44 last edited by
                      #22

                      @p3c0 I solved the problem! Even without doing custom roles. I just simplified it, adding some qRegisterMetaType. The solution is not as I want to be, but it works. For now, I just have to figure out how to hide the dummy items. Thank you for pointing out some direction.

                      P 1 Reply Last reply 4 Nov 2015, 05:51
                      0
                      • T TonyN
                        3 Nov 2015, 23:44

                        @p3c0 I solved the problem! Even without doing custom roles. I just simplified it, adding some qRegisterMetaType. The solution is not as I want to be, but it works. For now, I just have to figure out how to hide the dummy items. Thank you for pointing out some direction.

                        P Offline
                        P Offline
                        p3c0
                        Moderators
                        wrote on 4 Nov 2015, 05:51 last edited by p3c0 11 Apr 2015, 05:52
                        #23

                        @TonyN Congratulations :)
                        IMO you can use QAbstractItemModel with GridView(for grid like item positioning) or ListView (for list like item positioning). For hiding dummy items you can maintain a field for items and update it from the model whenever required.

                        157

                        T 1 Reply Last reply 4 Nov 2015, 14:25
                        0
                        • P p3c0
                          4 Nov 2015, 05:51

                          @TonyN Congratulations :)
                          IMO you can use QAbstractItemModel with GridView(for grid like item positioning) or ListView (for list like item positioning). For hiding dummy items you can maintain a field for items and update it from the model whenever required.

                          T Offline
                          T Offline
                          TonyN
                          wrote on 4 Nov 2015, 14:25 last edited by
                          #24

                          @p3c0 I certainly want to hear other opinion. I did attempt to use QAbstractItemModel, but then the GridView still treat model as a list!?
                          (my current solution is using QAbstractListModel with GridView, and compute item's index from its specified row and column, if there is no item at the requested index, I just return QVariant(). The rowCount() of QAbstractItemModel is the total item the can represent on the grid (row * column) )

                          P 1 Reply Last reply 5 Nov 2015, 05:45
                          0
                          • T TonyN
                            4 Nov 2015, 14:25

                            @p3c0 I certainly want to hear other opinion. I did attempt to use QAbstractItemModel, but then the GridView still treat model as a list!?
                            (my current solution is using QAbstractListModel with GridView, and compute item's index from its specified row and column, if there is no item at the requested index, I just return QVariant(). The rowCount() of QAbstractItemModel is the total item the can represent on the grid (row * column) )

                            P Offline
                            P Offline
                            p3c0
                            Moderators
                            wrote on 5 Nov 2015, 05:45 last edited by
                            #25

                            @TonyN GridView doesnot have the facility to get items using columns. AFAIK your current solution is the only way to go. Btw inside GridView you already have the index attached property.

                            157

                            1 Reply Last reply
                            0

                            22/25

                            3 Nov 2015, 23:44

                            • Login

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