Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. The better way to implement weird table or list
Forum Updated to NodeBB v4.3 + New Features

The better way to implement weird table or list

Scheduled Pinned Locked Moved Unsolved General and Desktop
25 Posts 5 Posters 4.8k Views 2 Watching
  • 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.
  • G Offline
    G Offline
    Gourmet
    wrote on last edited by
    #8

    Up...

    Can this be implemented with QML? I do not have much experience with QML - just only some settings for some widgets. Can list be constructed in QML? Can each item in list be constructred in QML? How do this? Is there any example of similar task solved in QML?

    J.HilkJ 1 Reply Last reply
    0
    • G Gourmet

      Up...

      Can this be implemented with QML? I do not have much experience with QML - just only some settings for some widgets. Can list be constructed in QML? Can each item in list be constructred in QML? How do this? Is there any example of similar task solved in QML?

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #9

      @Gourmet yes it can,

      My preferred method is,

      • create a class that contains all your information you want to show. Each Information has to be a Q_PROPERTY
      • create a QList<QObject*> with instances of your class as items
      • make that list available to QML
      • Set that list as model for a ListView
      • design your delegate in QML and access the class data via modelData.propertyName

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


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

      G 1 Reply Last reply
      3
      • J.HilkJ J.Hilk

        @Gourmet yes it can,

        My preferred method is,

        • create a class that contains all your information you want to show. Each Information has to be a Q_PROPERTY
        • create a QList<QObject*> with instances of your class as items
        • make that list available to QML
        • Set that list as model for a ListView
        • design your delegate in QML and access the class data via modelData.propertyName
        G Offline
        G Offline
        Gourmet
        wrote on last edited by
        #10

        @J.Hilk thanx but for me this looks little weird. I do not know yet how implement steps 3 and 5. Is there any example how do that? Or can anybody explain these steps deeper?

        J.HilkJ 1 Reply Last reply
        0
        • G Gourmet

          @J.Hilk thanx but for me this looks little weird. I do not know yet how implement steps 3 and 5. Is there any example how do that? Or can anybody explain these steps deeper?

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #11

          @Gourmet
          Just made a quick and dirty one ;)
          https://github.com/DeiVadder/ListViewExample


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


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

          G 1 Reply Last reply
          4
          • J.HilkJ J.Hilk

            @Gourmet
            Just made a quick and dirty one ;)
            https://github.com/DeiVadder/ListViewExample

            G Offline
            G Offline
            Gourmet
            wrote on last edited by Gourmet
            #12

            @J.Hilk thanx, I have first check if this will work in QGraphicsWidget. I need find the way around this bug.

            J.HilkJ 1 Reply Last reply
            0
            • G Gourmet

              @J.Hilk thanx, I have first check if this will work in QGraphicsWidget. I need find the way around this bug.

              J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on last edited by
              #13

              @Gourmet That I don't know, but it will work with QQuickWidget, if that helps ?

              https://doc.qt.io/Qt-5/qquickwidget.html


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


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

              G 1 Reply Last reply
              0
              • J.HilkJ J.Hilk

                @Gourmet That I don't know, but it will work with QQuickWidget, if that helps ?

                https://doc.qt.io/Qt-5/qquickwidget.html

                G Offline
                G Offline
                Gourmet
                wrote on last edited by
                #14

                @J.Hilk It must work. But will it or not - I am not sure yet. Unfortunately right now I have make other work. Will test this later.

                By the way - for QQuickWidget - will Window{} container in your main.qml needed or just only ListView{} required?

                J.HilkJ 1 Reply Last reply
                0
                • G Gourmet

                  @J.Hilk It must work. But will it or not - I am not sure yet. Unfortunately right now I have make other work. Will test this later.

                  By the way - for QQuickWidget - will Window{} container in your main.qml needed or just only ListView{} required?

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by J.Hilk
                  #15

                  @Gourmet for a qquickwidget it is irrelevant what the root element is, so yes it should work


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


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

                  G 1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    Gourmet
                    wrote on last edited by Gourmet
                    #16
                    This post is deleted!
                    1 Reply Last reply
                    0
                    • J.HilkJ J.Hilk

                      @Gourmet for a qquickwidget it is irrelevant what the root element is, so yes it should work

                      G Offline
                      G Offline
                      Gourmet
                      wrote on last edited by Gourmet
                      #17

                      @J.Hilk Your example works but my attempt does not. Here I include link to temporary zip with my source code.

                      https://dropmefiles.com/uezkn

                      Zip will be destroyed after week since this moment.

                      After setContextProperty() for QQuickWidget with 100 items it's size is 0,0. This tells line 20 in testlist.cpp. If line 14 in mainwindow.cpp is uncommented then one record with person_0 appears. But it does not have checkbox. I do not know how tune QML widget size to make it visible inside graphics scene. Line 12 in testlist.cpp doesn't help.

                      J.HilkJ 1 Reply Last reply
                      0
                      • G Gourmet

                        @J.Hilk Your example works but my attempt does not. Here I include link to temporary zip with my source code.

                        https://dropmefiles.com/uezkn

                        Zip will be destroyed after week since this moment.

                        After setContextProperty() for QQuickWidget with 100 items it's size is 0,0. This tells line 20 in testlist.cpp. If line 14 in mainwindow.cpp is uncommented then one record with person_0 appears. But it does not have checkbox. I do not know how tune QML widget size to make it visible inside graphics scene. Line 12 in testlist.cpp doesn't help.

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on last edited by
                        #18

                        @Gourmet
                        ok, couple of points,

                        1. seems like I was wrong, ListView can't be the root element - so I wrapped it in an Item{}

                        2. you QML objects needs a size or it won't draw anything. With setResizeMode(QQuickWidget::SizeRootObjectToView); set you have to resize it once from cpp side.
                          With setResizeMode(QQuickWidget::SizeViewToRootObject); you define the size with width:xxxx and height:yyyy of your root element in qml

                        3. set the rootContext property before you set the source, that will remove the not defined error


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


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

                        G 1 Reply Last reply
                        0
                        • J.HilkJ J.Hilk

                          @Gourmet
                          ok, couple of points,

                          1. seems like I was wrong, ListView can't be the root element - so I wrapped it in an Item{}

                          2. you QML objects needs a size or it won't draw anything. With setResizeMode(QQuickWidget::SizeRootObjectToView); set you have to resize it once from cpp side.
                            With setResizeMode(QQuickWidget::SizeViewToRootObject); you define the size with width:xxxx and height:yyyy of your root element in qml

                          3. set the rootContext property before you set the source, that will remove the not defined error

                          G Offline
                          G Offline
                          Gourmet
                          wrote on last edited by Gourmet
                          #19

                          @J.Hilk ok, I changed Window container to Item container and TestList code to follwing:

                          TestList::TestList(QWidget *p, uint _width) : QQuickWidget(p), width(_width)
                          {
                              qsrand(QTime::currentTime().second());
                              connect(this, SIGNAL(statusChanged(QQuickWidget::Status)), SLOT(changedStatus(QQuickWidget::Status)));
                             setResizeMode(QQuickWidget::SizeRootObjectToView);
                          }
                          
                          void TestList::FillList()
                          {
                              const int num = 100;
                              for( int i = 0; i < num; i++ )
                                  notebook.append( new NoteEntry("person_"+QString::number(i), qrand()%60+20, i%2) );
                              rootContext()->setContextProperty("DeathList",QVariant::fromValue(notebook));
                              setSource(QUrl("qrc:/main.qml"));
                              if( ! rootContext()->isValid() )
                              {
                                  qWarning()<<"QML is not valid";
                                  QApplication::quit();
                              }
                              resize( width, num*50 );
                          }
                          

                          Where width is ui->graphicsView.geometry().width(). Last resize calculates height as elements number multiplied to delegate height which is set in main.qml line 22. I do not know how extract this value for C++ code. The result is frustrating...

                          alt text

                          and bunch of error messages in console:
                          QOpenGLFramebufferObject: Framebuffer incomplete attachment.
                          QOpenGLFramebufferObject: Framebuffer incomplete attachment.
                          QOpenGLFramebufferObject: Framebuffer incomplete attachment.
                          QOpenGLFramebufferObject: Framebuffer incomplete attachment.
                          QOpenGLFramebufferObject: Framebuffer incomplete, missing attachment.

                          If I set width and height hard in main.qml and use setResizeMode(QQuickWidget::SizeViewToRootObject); then I see lines of my list. Of course only those who fit to it's size. With height 1000 px it works well and scrolls. Even it works with height 4050 - list has 81 person (from person_0 to person_80).
                          alt text
                          Checkboxes work, background color changes. But with height 4100 it breaks and looks like on the first picture here. So why this happens?

                          If this is some kind of memory limitation then I cannot use it. I need create application for possible couple hundreds of items. Each item can take about 100-150 pixels height. That means list can be up to 30000 pixels height. And may be more if the item height will grow.

                          J.HilkJ 1 Reply Last reply
                          0
                          • G Gourmet

                            @J.Hilk ok, I changed Window container to Item container and TestList code to follwing:

                            TestList::TestList(QWidget *p, uint _width) : QQuickWidget(p), width(_width)
                            {
                                qsrand(QTime::currentTime().second());
                                connect(this, SIGNAL(statusChanged(QQuickWidget::Status)), SLOT(changedStatus(QQuickWidget::Status)));
                               setResizeMode(QQuickWidget::SizeRootObjectToView);
                            }
                            
                            void TestList::FillList()
                            {
                                const int num = 100;
                                for( int i = 0; i < num; i++ )
                                    notebook.append( new NoteEntry("person_"+QString::number(i), qrand()%60+20, i%2) );
                                rootContext()->setContextProperty("DeathList",QVariant::fromValue(notebook));
                                setSource(QUrl("qrc:/main.qml"));
                                if( ! rootContext()->isValid() )
                                {
                                    qWarning()<<"QML is not valid";
                                    QApplication::quit();
                                }
                                resize( width, num*50 );
                            }
                            

                            Where width is ui->graphicsView.geometry().width(). Last resize calculates height as elements number multiplied to delegate height which is set in main.qml line 22. I do not know how extract this value for C++ code. The result is frustrating...

                            alt text

                            and bunch of error messages in console:
                            QOpenGLFramebufferObject: Framebuffer incomplete attachment.
                            QOpenGLFramebufferObject: Framebuffer incomplete attachment.
                            QOpenGLFramebufferObject: Framebuffer incomplete attachment.
                            QOpenGLFramebufferObject: Framebuffer incomplete attachment.
                            QOpenGLFramebufferObject: Framebuffer incomplete, missing attachment.

                            If I set width and height hard in main.qml and use setResizeMode(QQuickWidget::SizeViewToRootObject); then I see lines of my list. Of course only those who fit to it's size. With height 1000 px it works well and scrolls. Even it works with height 4050 - list has 81 person (from person_0 to person_80).
                            alt text
                            Checkboxes work, background color changes. But with height 4100 it breaks and looks like on the first picture here. So why this happens?

                            If this is some kind of memory limitation then I cannot use it. I need create application for possible couple hundreds of items. Each item can take about 100-150 pixels height. That means list can be up to 30000 pixels height. And may be more if the item height will grow.

                            J.HilkJ Offline
                            J.HilkJ Offline
                            J.Hilk
                            Moderators
                            wrote on last edited by
                            #20

                            @Gourmet
                            this works for me:

                            //mainWindow.h
                            #ifndef MAINWINDOW_H
                            #define MAINWINDOW_H
                            
                            #include <QMainWindow>
                            
                            namespace Ui {
                            class MainWindow;
                            }
                            class TestList;
                            class MainWindow : public QMainWindow
                            {
                                Q_OBJECT
                            
                            public:
                                explicit MainWindow(QWidget *parent = 0);
                                ~MainWindow();
                            
                            private:
                                Ui::MainWindow *ui;
                            protected:
                                void closeEvent(QCloseEvent*)override;
                                void resizeEvent(QResizeEvent *)override;
                            
                                TestList *tl= nullptr;
                            };
                            
                            #endif // MAINWINDOW_H
                            
                            //mainWindow.cpp
                            
                            #include "mainwindow.h"
                            #include "ui_mainwindow.h"
                            
                            #include <testlist.h>
                            
                            MainWindow::MainWindow(QWidget *parent) :
                                QMainWindow(parent),
                                ui(new Ui::MainWindow)
                            {
                                ui->setupUi(this);
                                tl = new TestList(0);
                                tl->FillList();
                                tl->move(0,0);
                                
                                QGraphicsView* gv = ui->graphicsView;
                                QGraphicsScene* scene;
                                gv->setScene( scene = new QGraphicsScene( tl->geometry(), this ) );
                                scene->addWidget( tl, Qt::Widget );
                            }
                            
                            MainWindow::~MainWindow()
                            {
                                delete ui;
                            }
                            
                            void MainWindow::closeEvent(QCloseEvent *)
                            {
                                QApplication::exit();
                            }
                            void MainWindow::resizeEvent(QResizeEvent *)
                            {
                                if(tl){
                                    tl->resize(ui->graphicsView->size());
                                }
                            }
                            
                            //main.qml
                            import QtQuick 2.9
                            import QtQuick.Controls 2.2
                            
                            Item{
                                id:root
                            
                                ListView {
                                    id:lView
                                    anchors.fill: parent
                            
                                    model: DeathList
                            
                                    orientation: ListView.Vertical
                            
                                    delegate: Rectangle {
                                        color: modelData.dead ? "darkred" : "white"
                            
                                        readonly property int numberOfVisibleItems: 10
                                        
                                        width: lView.width
                                        height: root.height /numberOfVisibleItems
                            
                                        Text {
                                            id:nameField
                                            anchors.left: parent.left
                                            anchors.verticalCenter: parent.verticalCenter
                                            text: modelData.name
                                            color: modelData.dead ? "white" : "black"
                                            width: contentWidth
                                        }
                            
                                        Text {
                                            anchors.left: nameField.right
                                            anchors.leftMargin: 20
                                            anchors.verticalCenter: parent.verticalCenter
                                            text: modelData.age + qsTr("years old")
                                            color: modelData.dead ? "white" : "black"
                                            width: contentWidth
                                        }
                            
                                        CheckBox {
                                            text: qsTr("is dead ?")
                                            anchors.right: parent.right
                                            anchors.top:parent.top
                                            anchors.bottom: parent.bottom
                                            checked: modelData.dead
                                            onCheckedChanged: modelData.dead = checked
                                        }
                                    }
                                }
                            }
                            

                            with a resize mode of SizeRootObjectToView


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


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

                            G 1 Reply Last reply
                            1
                            • J.HilkJ J.Hilk

                              @Gourmet
                              this works for me:

                              //mainWindow.h
                              #ifndef MAINWINDOW_H
                              #define MAINWINDOW_H
                              
                              #include <QMainWindow>
                              
                              namespace Ui {
                              class MainWindow;
                              }
                              class TestList;
                              class MainWindow : public QMainWindow
                              {
                                  Q_OBJECT
                              
                              public:
                                  explicit MainWindow(QWidget *parent = 0);
                                  ~MainWindow();
                              
                              private:
                                  Ui::MainWindow *ui;
                              protected:
                                  void closeEvent(QCloseEvent*)override;
                                  void resizeEvent(QResizeEvent *)override;
                              
                                  TestList *tl= nullptr;
                              };
                              
                              #endif // MAINWINDOW_H
                              
                              //mainWindow.cpp
                              
                              #include "mainwindow.h"
                              #include "ui_mainwindow.h"
                              
                              #include <testlist.h>
                              
                              MainWindow::MainWindow(QWidget *parent) :
                                  QMainWindow(parent),
                                  ui(new Ui::MainWindow)
                              {
                                  ui->setupUi(this);
                                  tl = new TestList(0);
                                  tl->FillList();
                                  tl->move(0,0);
                                  
                                  QGraphicsView* gv = ui->graphicsView;
                                  QGraphicsScene* scene;
                                  gv->setScene( scene = new QGraphicsScene( tl->geometry(), this ) );
                                  scene->addWidget( tl, Qt::Widget );
                              }
                              
                              MainWindow::~MainWindow()
                              {
                                  delete ui;
                              }
                              
                              void MainWindow::closeEvent(QCloseEvent *)
                              {
                                  QApplication::exit();
                              }
                              void MainWindow::resizeEvent(QResizeEvent *)
                              {
                                  if(tl){
                                      tl->resize(ui->graphicsView->size());
                                  }
                              }
                              
                              //main.qml
                              import QtQuick 2.9
                              import QtQuick.Controls 2.2
                              
                              Item{
                                  id:root
                              
                                  ListView {
                                      id:lView
                                      anchors.fill: parent
                              
                                      model: DeathList
                              
                                      orientation: ListView.Vertical
                              
                                      delegate: Rectangle {
                                          color: modelData.dead ? "darkred" : "white"
                              
                                          readonly property int numberOfVisibleItems: 10
                                          
                                          width: lView.width
                                          height: root.height /numberOfVisibleItems
                              
                                          Text {
                                              id:nameField
                                              anchors.left: parent.left
                                              anchors.verticalCenter: parent.verticalCenter
                                              text: modelData.name
                                              color: modelData.dead ? "white" : "black"
                                              width: contentWidth
                                          }
                              
                                          Text {
                                              anchors.left: nameField.right
                                              anchors.leftMargin: 20
                                              anchors.verticalCenter: parent.verticalCenter
                                              text: modelData.age + qsTr("years old")
                                              color: modelData.dead ? "white" : "black"
                                              width: contentWidth
                                          }
                              
                                          CheckBox {
                                              text: qsTr("is dead ?")
                                              anchors.right: parent.right
                                              anchors.top:parent.top
                                              anchors.bottom: parent.bottom
                                              checked: modelData.dead
                                              onCheckedChanged: modelData.dead = checked
                                          }
                                      }
                                  }
                              }
                              

                              with a resize mode of SizeRootObjectToView

                              G Offline
                              G Offline
                              Gourmet
                              wrote on last edited by Gourmet
                              #21

                              @J.Hilk I have found that Item height (and probably width) is limited to 4096 (2^12) pixels. When it grows up to 4097 pixels - the black field appears. Can this be some limitation of OpenGL engine used for QML? If yes then how break this limit? I need at least 2^15 pixels for height.

                              J.HilkJ 1 Reply Last reply
                              0
                              • G Gourmet

                                @J.Hilk I have found that Item height (and probably width) is limited to 4096 (2^12) pixels. When it grows up to 4097 pixels - the black field appears. Can this be some limitation of OpenGL engine used for QML? If yes then how break this limit? I need at least 2^15 pixels for height.

                                J.HilkJ Offline
                                J.HilkJ Offline
                                J.Hilk
                                Moderators
                                wrote on last edited by
                                #22

                                @Gourmet you don't need to set the width so high!

                                Only what's in the viewport, actually visible on your screen is rendered.
                                If you're forcing the width and hight of the component bigger you may only end up costing you performance.

                                ListView comes with a build in scrollarea/flickable. -> unlimited size, but you only see what's inside the viewport


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


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

                                G 1 Reply Last reply
                                1
                                • J.HilkJ J.Hilk

                                  @Gourmet you don't need to set the width so high!

                                  Only what's in the viewport, actually visible on your screen is rendered.
                                  If you're forcing the width and hight of the component bigger you may only end up costing you performance.

                                  ListView comes with a build in scrollarea/flickable. -> unlimited size, but you only see what's inside the viewport

                                  G Offline
                                  G Offline
                                  Gourmet
                                  wrote on last edited by Gourmet
                                  #23

                                  @J.Hilk looks like you did not read all I had wrote and my code. I need mandatory use QGraphicsScene to be able easy scale window content for different Android screen sizes.

                                  I do not use your last code - it does not solve the task. And does not contain anything new for me. I already have got my own working code - almost have got. But rested in size restriction.

                                  I tried use Window container - it gives scrollable list of all 100 items in my TestList. But this window appears outside of main window. I need list inside it. When I use Item container it appears inside main window. That's what I need. And all works fine as needed - long list scrolls inside QGraphicsScene. And it scales as well. But looks like Item's size is limited to 4096x4096 pixels. Is there any way to grow this limit? How can I create Item with size 600x32767?

                                  PS: Ooops... looks like 4096x4096 is not the Item limit. But a limit of something in QGraphiscScene instead. May be QGraphicsItem linit. Or QGraphicsProxyWidget. I now removed Item from code and left only ListView. With setting it's height to 4096 it works well (yes, without root Item). But with settings it's height to 4097 it breaks.

                                  1 Reply Last reply
                                  0
                                  • G Offline
                                    G Offline
                                    Gourmet
                                    wrote on last edited by Gourmet
                                    #24

                                    I have tested limits of QGraphicsProxyWidget and QGraphicsItem - they work well with huge push button, 32000 pixels height. But large ListView works well too inside Window{}. Perhaps problem is in Item{}'s restriction. Otherwise it is a bug...

                                    1 Reply Last reply
                                    0
                                    • G Offline
                                      G Offline
                                      Gourmet
                                      wrote on last edited by
                                      #25

                                      Found posting with similar problem. Unfortunately no solution there.

                                      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