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 TonyN

    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!

    p3c0P Offline
    p3c0P Offline
    p3c0
    Moderators
    wrote on 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
    0
    • p3c0P p3c0

      @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 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.

      p3c0P 1 Reply Last reply
      0
      • T TonyN

        @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.

        p3c0P Offline
        p3c0P Offline
        p3c0
        Moderators
        wrote on last edited by
        #10

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

        157

        T 1 Reply Last reply
        0
        • p3c0P p3c0

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

          T Offline
          T Offline
          TonyN
          wrote on 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?

          p3c0P 1 Reply Last reply
          0
          • T TonyN

            @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?

            p3c0P Offline
            p3c0P Offline
            p3c0
            Moderators
            wrote on 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 last edited by
              #13

              Hi TonyN,

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

              Thanks!

              1 Reply Last reply
              0
              • T TonyN

                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 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
                0
                • T TonyN

                  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 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
                          }
                      }
                  }
                  
                  p3c0P 1 Reply Last reply
                  0
                  • T Offline
                    T Offline
                    TuanLT
                    wrote on 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
                    0
                    • T TuanLT

                      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 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

                        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
                                }
                            }
                        }
                        
                        p3c0P Offline
                        p3c0P Offline
                        p3c0
                        Moderators
                        wrote on 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
                        0
                        • p3c0P p3c0

                          @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 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();
                          }
                          
                          p3c0P 1 Reply Last reply
                          0
                          • T TonyN

                            @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();
                            }
                            
                            p3c0P Offline
                            p3c0P Offline
                            p3c0
                            Moderators
                            wrote on 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
                            0
                            • p3c0P p3c0

                              @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 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
                              • p3c0P p3c0

                                @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 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.

                                p3c0P 1 Reply Last reply
                                0
                                • T TonyN

                                  @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.

                                  p3c0P Offline
                                  p3c0P Offline
                                  p3c0
                                  Moderators
                                  wrote on last edited by p3c0
                                  #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
                                  0
                                  • p3c0P p3c0

                                    @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 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) )

                                    p3c0P 1 Reply Last reply
                                    0
                                    • T TonyN

                                      @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) )

                                      p3c0P Offline
                                      p3c0P Offline
                                      p3c0
                                      Moderators
                                      wrote on 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

                                      • Login

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