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. QListView or Custom List of Widget?
Qt 6.11 is out! See what's new in the release blog

QListView or Custom List of Widget?

Scheduled Pinned Locked Moved General and Desktop
7 Posts 3 Posters 8.9k Views 1 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.
  • M Offline
    M Offline
    maximus
    wrote on last edited by
    #1

    Hi,

    I'm trying to achieve an interface similar to :
    https://www.dropbox.com/s/94sdayh0q5y4vfz/workoutList.png

    Of course this is not in QT. It is a web interface Copyright @Garmin for that.
    Basically It's a list, it's possible to add/remove/edit element to the list.
    The individual element of the list is a box containing info.

    I am thinking maybe a QList of custom QWidget to achieve that?
    Because I am not sure that QListView would be powerfull enought to let me customize my element in each row?
    Anyone with more experience in QT can recommend me?
    Thanks!


    Free Indoor Cycling Software - https://maximumtrainer.com

    1 Reply Last reply
    0
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Qt Champions 2022
      wrote on last edited by
      #2

      You can do that. You need to have custom delegate to alter the way the cells are shown in ListView. QList and Widget is not the right way and it require lot of custom code.

      You can look @ following link. It will help you.

      http://doc.qt.digia.com/qq/qq24-delegates.html

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      1 Reply Last reply
      0
      • S Offline
        S Offline
        Sam
        wrote on last edited by
        #3

        Inorder to do that you can follow the steps

        1. Create a custom widget that holds all the above data.
        2. You need to add the instance of the widget to the model.
        3. You need to have a custom delegate that should implement
        • paint()
        • createEditor()
        • setEditorData()
        • setModelData()

        for the delegate, in the paint() function you need to renders/fake's the widget with the data it holds for the current QModelIndex, then when a cell is clicked u need to create the actual widget and display.

        This method is recommended as there is another way to add the widget to the ListView using setIndexWidget() but it effects the performance heavily.

        Regards
        Sam

        1 Reply Last reply
        0
        • M Offline
          M Offline
          maximus
          wrote on last edited by
          #4

          Thanks for your help guys.

          I finally opted to go for a custom QAbstractTableModel & TableView instead since I already used that one (reuse some of my code). I will try to find how to display widget in individual cell, but I guess delegate should be able to do it, after i'll have to connect those widget so that when they are edited the model get edited.
          I'll post back when I get some working code :0


          Free Indoor Cycling Software - https://maximumtrainer.com

          1 Reply Last reply
          0
          • M Offline
            M Offline
            maximus
            wrote on last edited by
            #5

            Hey guys,

            I'm working on my Model, I used the "Address Book ":http://qt-project.org/doc/qt-5/qtwidgets-itemviews-addressbook-example.html and the "spinBox delegate":http://qt-project.org/doc/qt-5/qtwidgets-itemviews-spinboxdelegate-example.html example and it helped me a lot.

            I'm kind of stuck on a last thing. I have editor for normal field that work well (int, QString, QComboBox)
            But I have an editor that needs to edit 4 fields of my Object at the same time (int, double, double, int)

            I can retrieve that data from the model fine with data().
            but when it's time to update the model with setData(), I have some problem. I think it's a conversion problem with QVariant and my custom type.

            Here is my use case interface :
            https://www.dropbox.com/s/euguunbqx39eky7/QVariantConvert.png

            Here is my code :

            @//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {

            /// Type
            if (index.column() == 0) {
                IntervalComboBox *comboBox = static_cast<IntervalComboBox*>(editor);
                int value = comboBox->currentIndex();
                model->setData(index, value, Qt::EditRole);
            }
            
            /// Duration
            else if (index.column() == 1) {
                QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
                QTime time1 = timeEdit->time();
                model->setData(index, time1, Qt::EditRole);
            }
            
            /// Display Message
            else if (index.column() == 2) {
                QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
                QString msg = lineEdit->text();
                model->setData(index, msg, Qt::EditRole);
            }
            
            /// Target Power (4 fields in Interval to change)
            else if (index.column() == 3) {
            
                EditTargetPowerWidget *targetWidget = static_cast<EditTargetPowerWidget*>(editor);
            
                int targetStepPower = targetWidget->stepComboBox->currentIndex();
                Interval::StepType stepType = static_cast<Interval::StepType>( targetStepPower );
                double startFTP = targetWidget->targetStartValue->value()/100;
                double endFTP = targetWidget->targetEndValue->value()/100;
                int range = targetWidget->targetRangeValue->value();
            
            
                std::shared_ptr<Interval> interval(new Interval() );
                interval->setPowerData(stepType, startFTP, endFTP, range);
                QVariant variant = interval;
                //        model->setData(index, variant, Qt::EditRole);
            
            
                /// CONVERT TEST (Should be done in setData() of the model when it works..)
                qDebug() << "Test CAN CONVERT2?" << variant.canConvert<std::shared_ptr<Interval>>();  //return false?
            
                /// Trying anyway...
                std::shared_ptr<Interval> interval2(qvariant_cast<std::shared_ptr<Interval>>( variant ));
                qDebug() << "TEST CONVERT:" << interval2->getFTP_start();
            
            
            }
            
            else {
                QStyledItemDelegate::setModelData(editor, model, index);
            }
            

            }@

            SetEditorData (retrieve data) -- Working
            @
            //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            void SpinBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {

            /// Type
            if (index.column() == 0) {
                int value =  index.model()->data(index, Qt::DisplayRole).toInt();
                IntervalComboBox *comboBox = static_cast<IntervalComboBox*>(editor);
                comboBox->setCurrentIndex(value);
            }
            
            /// Duration
            else if (index.column() == 1) {
                QTime time = index.model()->data(index, Qt::DisplayRole).toTime();
                QTimeEdit *timeEdit = static_cast<QTimeEdit*>(editor);
                timeEdit->setTime( time );
            }
            
            /// Display Message
            else if (index.column() == 2) {
            
                QString msg = index.model()->data(index, Qt::DisplayRole).toString();
                QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
                lineEdit->setText(msg);
            }
            
            /// Target Power
            else if (index.column() == 3) {
            
                std::shared_ptr<Interval> interval(qvariant_cast<std::shared_ptr<Interval>>( index.model()->data(index, Qt::DisplayRole) ));
            
                int targetStepPower = interval->getPowerStepType();
                double startFTP = interval->getFTP_start() * 100;
                double endFTP = interval->getFTP_end() * 100;
                int range = interval->getFTP_range();
            
                EditTargetPowerWidget *targetWidget = static_cast<EditTargetPowerWidget*>(editor);
                targetWidget->stepComboBox->setCurrentIndex(targetStepPower);
                targetWidget->targetStartValue->setValue(startFTP);
                targetWidget->targetEndValue->setValue(endFTP);
                targetWidget->targetRangeValue->setValue(range);
            
            }
            
            else {
                QStyledItemDelegate::setEditorData(editor, index);
            }
            

            }@

            Thanks if you can help me with QVariant, it is giving me headaches :)
            Forgot to say I already added :Q_DECLARE_METATYPE(std::shared_ptr<Interval>) in my Interval class


            Free Indoor Cycling Software - https://maximumtrainer.com

            1 Reply Last reply
            0
            • M Offline
              M Offline
              maximus
              wrote on last edited by
              #6

              Fixed!

              Was a stupid error

              I changed
              "QVariant variant = interval;"
              with
              "QVariant variant = QVariant::fromValue( interval );"

              Thanks!


              Free Indoor Cycling Software - https://maximumtrainer.com

              1 Reply Last reply
              0
              • M Offline
                M Offline
                maximus
                wrote on last edited by
                #7

                So I finally chose to use a QListView with a custom ListModel that subclass QAbstractListModel.

                1- Here is my current interface :
                https://www.dropbox.com/s/dg1n0kozcwoa2xm/currentWorkoutList.png
                It's just a QListView with 1 custom widget per row, that is returned in the createEditor function of my delegate. In the paint function of my delegate, I paint the widget directly in the painter.

                2- Here is what I would like :
                https://www.dropbox.com/s/uzu10fmv1w2r7fj/workoutEx.png

                My problem :
                I would like to have the kind of "repeat" box (see #2), to make possible a loop that is defined by the user.

                I have tought of multiple way to do that, maybe change my model to a treeItemModel, but I need a lot of coding and from the "documentation":http://qt-project.org/doc/qt-5.0/qtwidgets/qtreeview.html, it looks really complex for what I need.

                Another solution would be to have a List of QListView, each QListView has a main header that display the number of loop. But with this way, i'm not sure I would be able to drap&drop item from one QListView to another.
                Anyone with experience know if this is possible? Thanks in advance.

                Max
                http://maximumtrainer.com/

                [Edit: drag and drop possible between multiple ListView, when using" QMimeData":http://qt-project.org/doc/qt-5.0/qtcore/qmimedata.html#details with the same type, i'll post code when I get it working]


                Free Indoor Cycling Software - https://maximumtrainer.com

                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