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. Need help from QT Experts ( Model / View for QDateTimeEdit widget)

Need help from QT Experts ( Model / View for QDateTimeEdit widget)

Scheduled Pinned Locked Moved Unsolved General and Desktop
model-viewqdatawidgetmappqdatetimeedit
27 Posts 5 Posters 4.7k 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.
  • S Offline
    S Offline
    SGaist
    Lifetime Qt Champion
    wrote on 6 Jun 2019, 21:00 last edited by SGaist 6 Jul 2019, 08:29
    #2

    Hi and welcome to devnet,

    You can create a custom widget with 6 properties matching your model content. The you can use the QDataWidgetMapper::addMapping overload that takes a property name.

    Sadly my suggestion is not possible with the current implementation of QDataWidgetMapper.

    [edit: SGaist]

    Interested in AI ? www.idiap.ch
    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

    J 1 Reply Last reply 6 Jun 2019, 21:28
    2
    • S SGaist
      6 Jun 2019, 21:00

      Hi and welcome to devnet,

      You can create a custom widget with 6 properties matching your model content. The you can use the QDataWidgetMapper::addMapping overload that takes a property name.

      Sadly my suggestion is not possible with the current implementation of QDataWidgetMapper.

      [edit: SGaist]

      J Offline
      J Offline
      JonB
      wrote on 6 Jun 2019, 21:28 last edited by JonB 6 Jun 2019, 21:28
      #3

      @SGaist
      As I understand it, the OP has 6 properties. You will call addMapping() 6 times to map each of these to the same widget? I thought (haven't used it) QDataWidgetMapper gave you one distinct widget per distinct property? Won't something go wrong with multiple properties mapped to a single widget?

      1 Reply Last reply
      0
      • C Offline
        C Offline
        chakry
        wrote on 7 Jun 2019, 07:21 last edited by
        #4

        Hi SGaist,JonB thank you very much , This is my first question happy to see people replying . I am new to QT development as well.

        I tried that as well , sorry didint mention that . I have created a custom widget(extending existing) with six more properties and then used addMapping to map each property. This didnt work , it was working only for the last property . Looks like As JonB mentioned QDataWidgetMapper will only work with one property per one widget.

        J 1 Reply Last reply 7 Jun 2019, 07:51
        0
        • C chakry
          7 Jun 2019, 07:21

          Hi SGaist,JonB thank you very much , This is my first question happy to see people replying . I am new to QT development as well.

          I tried that as well , sorry didint mention that . I have created a custom widget(extending existing) with six more properties and then used addMapping to map each property. This didnt work , it was working only for the last property . Looks like As JonB mentioned QDataWidgetMapper will only work with one property per one widget.

          J Offline
          J Offline
          JonB
          wrote on 7 Jun 2019, 07:51 last edited by
          #5

          @chakry
          That's kind of what I thought (or it would error). However, be aware that @SGaist is an expert: unless he mis-read your question, he usually knows what he is talking about!

          1 Reply Last reply
          0
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 7 Jun 2019, 08:27 last edited by
            #6

            @JonB said in Need help from QT Experts ( Model / View for QDateTimeEdit widget):

            @chakry
            That's kind of what I thought (or it would error). However, be aware that @SGaist is an expert: unless he mis-read your question, he usually knows what he is talking about!

            Thanks for the flowers, but I can be wrong and that's one occurrence. I had the same assumption you have but taking a look at the current QDataWidgetMapper implementation, it doesn't handle mapping of several properties on the same widget. However, I don't know whether it's on purpose in which case the documentation should be updated to reflect that or if it just a case of "use case did not happen before" in which case it could be considered a bug. From the looks of the API, I think the original design was really one different widget per section but that is pure speculation.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            J 1 Reply Last reply 7 Jun 2019, 08:31
            2
            • S SGaist
              7 Jun 2019, 08:27

              @JonB said in Need help from QT Experts ( Model / View for QDateTimeEdit widget):

              @chakry
              That's kind of what I thought (or it would error). However, be aware that @SGaist is an expert: unless he mis-read your question, he usually knows what he is talking about!

              Thanks for the flowers, but I can be wrong and that's one occurrence. I had the same assumption you have but taking a look at the current QDataWidgetMapper implementation, it doesn't handle mapping of several properties on the same widget. However, I don't know whether it's on purpose in which case the documentation should be updated to reflect that or if it just a case of "use case did not happen before" in which case it could be considered a bug. From the looks of the API, I think the original design was really one different widget per section but that is pure speculation.

              J Offline
              J Offline
              JonB
              wrote on 7 Jun 2019, 08:31 last edited by JonB 6 Jul 2019, 08:32
              #7

              @SGaist

              Thanks for the flowers

              Since I believe you are Swiss, I send you some "Leontopodium" ("lion's paw", Edelweiss), your national flower ;-)

              1 Reply Last reply
              2
              • C Offline
                C Offline
                chakry
                wrote on 7 Jun 2019, 16:13 last edited by chakry 6 Jul 2019, 16:16
                #8

                Thank you for your suggestions :). This in general gets me into a new question , suppose i have a database of multiple cells that i want to show them in a single widget then i have the same problem right ? i cannot do that , are there any other ways ?

                isn't it a use case which might be coming in working environments or am i the only one landed there as i don't see much people talking about it :).

                for example i have custom widget with 10 sliders on it where i want to have a database model that updates 10 cells(value) it should be vice versa (if the cells are updated ( background by some one else) and in turn the sliders change automatically ). I know with signals and slots its possible but if i have many of these scenarios like this in a project then it will be a lot of signal/slots and updates right, difficult to track in case of errors ? any other options todo such things .

                @I may be wrong in thinking ( writing whatever on my mind :))

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 8 Jun 2019, 07:19 last edited by
                  #9

                  You'll likely have these 10 sliders in one custom widget so you would have the mapper within that widget and then map each slider independently.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  C 1 Reply Last reply 12 Jun 2019, 16:37
                  0
                  • S Offline
                    S Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 9 Jun 2019, 07:26 last edited by
                    #10

                    As for your single widget with multiple properties, here's a workaround taking advantage of Qt's dynamic properties. Note that I don't find it elegant because it requires one widget per property but at least you can have your single QDateTimeEdit used.

                    class QDWMProxy : public QWidget
                    {
                    public:
                        /*!
                            Set which property should be set on the target
                        */
                        void setMapping(QWidget *target, const QByteArray& propertyName)
                        {
                            _target = target;
                            _propertyName = propertyName;
                        }
                    
                        bool event(QEvent *event) override
                        {
                            if (event->type() == QEvent::DynamicPropertyChange) {
                                QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent *>(event);
                                if (pe->propertyName() == _propertyName) {
                                    _target->setProperty(_propertyName, property(_propertyName));
                                    event->accept();
                                    return true;
                                }
                            }
                            return QWidget::event(event);
                        }
                    
                    private:
                        QWidget *_target;
                        QByteArray _propertyName;
                    };
                    

                    You'll create one proxy per properties and use it for the QDataWidgetMapper mapping function. Don't forget to handle their deletion appropriately.

                    Dummy main.cpp example:

                        MyCustomWidget widget;
                        QDWMProxy proxyHours;
                        proxy1.setMapping(&widget, "hours");
                        QDWMProxy proxyMinutes;
                        proxy2.setMapping(&widget, "minutes");
                        QDataWidgetMapper mapper;
                        mapper.setModel(model);
                        mapper.addMapping(&proxyHours, 0, "hours");
                        mapper.addMapping(&proxyMinutes, 1, "minutes");
                        mapper.toFirst();
                        widget.show();
                    

                    I'll let you replace your model and widget.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    C 2 Replies Last reply 12 Jun 2019, 17:04
                    4
                    • S SGaist
                      8 Jun 2019, 07:19

                      You'll likely have these 10 sliders in one custom widget so you would have the mapper within that widget and then map each slider independently.

                      C Offline
                      C Offline
                      chakry
                      wrote on 12 Jun 2019, 16:37 last edited by
                      #11

                      @SGaist Thank you. you are right , that works. This may be a wrong example.

                      1 Reply Last reply
                      0
                      • S SGaist
                        9 Jun 2019, 07:26

                        As for your single widget with multiple properties, here's a workaround taking advantage of Qt's dynamic properties. Note that I don't find it elegant because it requires one widget per property but at least you can have your single QDateTimeEdit used.

                        class QDWMProxy : public QWidget
                        {
                        public:
                            /*!
                                Set which property should be set on the target
                            */
                            void setMapping(QWidget *target, const QByteArray& propertyName)
                            {
                                _target = target;
                                _propertyName = propertyName;
                            }
                        
                            bool event(QEvent *event) override
                            {
                                if (event->type() == QEvent::DynamicPropertyChange) {
                                    QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent *>(event);
                                    if (pe->propertyName() == _propertyName) {
                                        _target->setProperty(_propertyName, property(_propertyName));
                                        event->accept();
                                        return true;
                                    }
                                }
                                return QWidget::event(event);
                            }
                        
                        private:
                            QWidget *_target;
                            QByteArray _propertyName;
                        };
                        

                        You'll create one proxy per properties and use it for the QDataWidgetMapper mapping function. Don't forget to handle their deletion appropriately.

                        Dummy main.cpp example:

                            MyCustomWidget widget;
                            QDWMProxy proxyHours;
                            proxy1.setMapping(&widget, "hours");
                            QDWMProxy proxyMinutes;
                            proxy2.setMapping(&widget, "minutes");
                            QDataWidgetMapper mapper;
                            mapper.setModel(model);
                            mapper.addMapping(&proxyHours, 0, "hours");
                            mapper.addMapping(&proxyMinutes, 1, "minutes");
                            mapper.toFirst();
                            widget.show();
                        

                        I'll let you replace your model and widget.

                        C Offline
                        C Offline
                        chakry
                        wrote on 12 Jun 2019, 17:04 last edited by
                        #12

                        @SGaist Thank you. Good trick, it worked . Mapping works , if the model data is updated then the widget is updated . But when the widget is updated then the model is not updated automatically . I am still looking a reason for this. Probably missing something , will post once it is completely working.

                        1 Reply Last reply
                        0
                        • V Offline
                          V Offline
                          VRonin
                          wrote on 12 Jun 2019, 18:14 last edited by VRonin 6 Dec 2019, 18:17
                          #13

                          Just trying to understand. An example always helps me.
                          So your model looks like:

                          • Parent A
                            • 2019-12-25
                            • 13:58:15
                            • Wednesday
                            • 13
                            • 58
                            • 15
                          • Parent B
                            • 2019-05-30
                            • 20:30:55
                            • Thursday
                            • 20
                            • 30
                            • 55

                          And you want it displayed as a list that appears

                          • 2019-12-25 13:58:15
                          • 2019-05-30 20:30:55

                          And when one item of that list gets modified then the children of the tree get modified accordingly.
                          Is the above an accurate representation? (if so there is a solution that requires a proxy).

                          Or do you want a widget completely external to the representation of the data?

                          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                          ~Napoleon Bonaparte

                          On a crusade to banish setIndexWidget() from the holy land of Qt

                          1 Reply Last reply
                          0
                          • C Offline
                            C Offline
                            chakry
                            wrote on 13 Jun 2019, 07:38 last edited by chakry
                            #14

                            HI @VRonin ,

                            Model is almost correct small difference is ( date is also broken to a separate child as below)

                            Parent A

                            2019
                            12
                            25
                            13
                            58
                            15
                            Wednesday ( this one is not must)

                            And you want it displayed as a list that appears ( not as a list but i want to display and edit using a QDateTimeEdit widget or similar)

                            2019-12-25 13:58:15
                            2019-05-30 20:30:55
                            

                            if it is a tree widget or tree view then it is no problem it works directly.( element wise )

                            proxy , i have read about this and tried to implement but did not succeed( it is easier in a table widget or Tree i think). do you have a example of this to a seperate widget?

                            V 1 Reply Last reply 13 Jun 2019, 18:13
                            0
                            • S SGaist
                              9 Jun 2019, 07:26

                              As for your single widget with multiple properties, here's a workaround taking advantage of Qt's dynamic properties. Note that I don't find it elegant because it requires one widget per property but at least you can have your single QDateTimeEdit used.

                              class QDWMProxy : public QWidget
                              {
                              public:
                                  /*!
                                      Set which property should be set on the target
                                  */
                                  void setMapping(QWidget *target, const QByteArray& propertyName)
                                  {
                                      _target = target;
                                      _propertyName = propertyName;
                                  }
                              
                                  bool event(QEvent *event) override
                                  {
                                      if (event->type() == QEvent::DynamicPropertyChange) {
                                          QDynamicPropertyChangeEvent *pe = static_cast<QDynamicPropertyChangeEvent *>(event);
                                          if (pe->propertyName() == _propertyName) {
                                              _target->setProperty(_propertyName, property(_propertyName));
                                              event->accept();
                                              return true;
                                          }
                                      }
                                      return QWidget::event(event);
                                  }
                              
                              private:
                                  QWidget *_target;
                                  QByteArray _propertyName;
                              };
                              

                              You'll create one proxy per properties and use it for the QDataWidgetMapper mapping function. Don't forget to handle their deletion appropriately.

                              Dummy main.cpp example:

                                  MyCustomWidget widget;
                                  QDWMProxy proxyHours;
                                  proxy1.setMapping(&widget, "hours");
                                  QDWMProxy proxyMinutes;
                                  proxy2.setMapping(&widget, "minutes");
                                  QDataWidgetMapper mapper;
                                  mapper.setModel(model);
                                  mapper.addMapping(&proxyHours, 0, "hours");
                                  mapper.addMapping(&proxyMinutes, 1, "minutes");
                                  mapper.toFirst();
                                  widget.show();
                              

                              I'll let you replace your model and widget.

                              C Offline
                              C Offline
                              chakry
                              wrote on 13 Jun 2019, 14:26 last edited by chakry
                              #15

                              @SGaist Dear SGaist, I could not make it 100 % working , so posting here the widget code. I have tried a simple version to check functionality.

                              problem: widget mapper mapping to property . updates property when model changed , does not update model when property changed. I didn't understand how widget mapper gets property change info.

                              here is code

                              class QmDateTimeEdit : public QDateTimeEdit {
                              Q_OBJECT

                              Q_PROPERTY(uint16_t dateYear READ dateYear WRITE setDateYear NOTIFY dateYearChanged USER true)
                              Q_PROPERTY(uint16_t dateMonth READ dateMonth WRITE setDateMonth NOTIFY dateMonthChanged USER true)
                              Q_PROPERTY(uint16_t dateDay READ dateDay WRITE setDateDay NOTIFY dateDayChanged USER true)
                              

                              public:
                              explicit QmDateTimeEdit(QWidget* parent = nullptr);

                              uint16_t dateYear() const { return mYear; }
                              uint16_t dateMonth() const { return mMonth; }
                              uint16_t dateDay() const { return mDay; }
                              
                              QDateTime dateTime() const;
                              

                              signals:

                              void dateYearChanged(const uint16_t& dateYear);
                              void dateMonthChanged(const uint16_t& dateMonth);
                              void dateDayChanged(const uint16_t& dateDay);
                              

                              private slots:

                              void valueChanged(const QDateTime& dateTime);
                              void setDateTime(const QDateTime& dateTime);
                              void setDateDay(uint16_t dateDay);
                              void setDateYear(uint16_t dateYear);
                              void setDateMonth(uint16_t dateMonth);
                              

                              private:

                              uint16_t mYear;
                              uint16_t mMonth;
                              uint16_t mDay;
                              

                              };

                              // when ever valueChanged() occurs i just set 3 values (mYear , mMonth and mDay) and emit 3 signals . I expected this should update the model data but it doesn't.

                              QmDateTimeEdit::QmDateTimeEdit(QWidget* parent)
                              : QDateTimeEdit(parent)
                              {
                              connect(this, &QDateTimeEdit::dateTimeChanged, this, &QmDateTimeEdit::valueChanged);
                              }

                              void QmDateTimeEdit::setDateYear(uint16_t dateYear)
                              {

                              mYear = dateYear;
                              qDebug() << "Year changed" << mYear;	
                              

                              }

                              void QmDateTimeEdit::setDateMonth(uint16_t dateMonth)
                              {

                              mMonth = dateMonth;
                              qDebug() << "Month changed" << mMonth;	
                              

                              }

                              void QmDateTimeEdit::setDateDay(uint16_t dateDay)
                              {

                              mDay = dateDay;
                              qDebug() << "Day changed" << mDay << this->parent();	
                              

                              }

                              void QmDateTimeEdit::valueChanged(const QDateTime& dateTime)
                              {

                              setDateYear(dateTime.date().year());
                              setDateMonth(dateTime.date().month());
                              setDateDay(dateTime.date().day());
                              
                              emit dateYearChanged(dateTime.date().year());
                              emit dateMonthChanged(dateTime.date().month());	
                              emit dateDayChanged(dateTime.date().day());
                              

                              }

                              1 Reply Last reply
                              0
                              • T Offline
                                T Offline
                                tajny_agent
                                wrote on 13 Jun 2019, 17:20 last edited by
                                #16

                                You can use QDataWidgetMapper with custom delegate.

                                void MyDelegate::setEditorData(QWidget* parent, const QModelIndex& index) const
                                {
                                  if (auto dte = qobject_cast<QDateTimeEdit*>(editor); dte) {
                                    auto* model = index.model();
                                    const auto& year = model->index(0, 0, index.parent()).data().toString();
                                    const auto& month = model->index(1, 0, index.parent()).data().toString();
                                    // ...
                                    QDateTime dt = QDateTime::fromString(/*combine above to QDateTime*/);
                                    dte->setDateTime(dt);
                                  }
                                }
                                

                                Then map your QDateTimeEdit with QDataWidgetMapper, set delegate. and voila

                                C 1 Reply Last reply 14 Jun 2019, 09:57
                                0
                                • C chakry
                                  13 Jun 2019, 07:38

                                  HI @VRonin ,

                                  Model is almost correct small difference is ( date is also broken to a separate child as below)

                                  Parent A

                                  2019
                                  12
                                  25
                                  13
                                  58
                                  15
                                  Wednesday ( this one is not must)

                                  And you want it displayed as a list that appears ( not as a list but i want to display and edit using a QDateTimeEdit widget or similar)

                                  2019-12-25 13:58:15
                                  2019-05-30 20:30:55
                                  

                                  if it is a tree widget or tree view then it is no problem it works directly.( element wise )

                                  proxy , i have read about this and tried to implement but did not succeed( it is easier in a table widget or Tree i think). do you have a example of this to a seperate widget?

                                  V Offline
                                  V Offline
                                  VRonin
                                  wrote on 13 Jun 2019, 18:13 last edited by VRonin
                                  #17

                                  Something like this minimal example is what you want or did I miss something?

                                  #include <QApplication>
                                  #include <QTreeWidget>
                                  #include <QVBoxLayout>
                                  #include <QDateTimeEdit>
                                  #include <QStandardItemModel>
                                  class ExampleWid : public QWidget{
                                      //Q_OBJECT
                                      Q_DISABLE_COPY(ExampleWid)
                                  public:
                                      explicit ExampleWid(QWidget *parent = Q_NULLPTR)
                                          :QWidget(parent)
                                          ,view(new QTreeView(this))
                                          ,editor(new QDateTimeEdit(this))
                                      {
                                          QAbstractItemModel* model = new QStandardItemModel(this);
                                          model->insertColumn(0);
                                          model->insertRows(0,2);
                                          QModelIndex parIdx= model->index(0,0);
                                          model->setData(parIdx,QStringLiteral("Parent A"));
                                          model->insertColumn(0,parIdx);
                                          model->insertRows(0,7,parIdx);
                                          model->setData(model->index(0,0,parIdx),2019);
                                          model->setData(model->index(1,0,parIdx),12);
                                          model->setData(model->index(2,0,parIdx),25);
                                          model->setData(model->index(3,0,parIdx),13);
                                          model->setData(model->index(4,0,parIdx),58);
                                          model->setData(model->index(5,0,parIdx),15);
                                          model->setData(model->index(6,0,parIdx),QStringLiteral("Wednesday"));
                                          parIdx= model->index(1,0);
                                          model->setData(parIdx,QStringLiteral("Parent B"));
                                          model->insertColumn(0,parIdx);
                                          model->insertRows(0,7,parIdx);
                                          model->setData(model->index(0,0,parIdx),2019);
                                          model->setData(model->index(1,0,parIdx),5);
                                          model->setData(model->index(2,0,parIdx),30);
                                          model->setData(model->index(3,0,parIdx),20);
                                          model->setData(model->index(4,0,parIdx),30);
                                          model->setData(model->index(5,0,parIdx),55);
                                          model->setData(model->index(6,0,parIdx),QStringLiteral("Thursday"));
                                  
                                          view->setModel(model);
                                          QVBoxLayout* minLay = new QVBoxLayout(this);
                                          minLay->addWidget(editor);
                                          minLay->addWidget(view);
                                          QObject::connect(view->selectionModel(),&QItemSelectionModel::currentChanged,this,[this](QModelIndex idx)->void{
                                              if(!idx.isValid())
                                                  return;
                                              while(idx.parent().isValid())
                                                  idx =idx.parent();
                                              lastIdx = QPersistentModelIndex();
                                              editor->setDateTime(QDateTime(
                                                  QDate(
                                                      idx.model()->index(0,0,idx).data().toInt()
                                                      ,idx.model()->index(1,0,idx).data().toInt()
                                                      ,idx.model()->index(2,0,idx).data().toInt()
                                                  )
                                                  , QTime(
                                                      idx.model()->index(3,0,idx).data().toInt()
                                                      ,idx.model()->index(4,0,idx).data().toInt()
                                                      ,idx.model()->index(5,0,idx).data().toInt()
                                                  )
                                              ));
                                              lastIdx = idx;
                                          });
                                          QObject::connect(editor,&QDateTimeEdit::dateTimeChanged,this,[this](const QDateTime &datetime)->void {
                                              if(!lastIdx.isValid())
                                                  return;
                                              QAbstractItemModel * model = view->model();
                                              model->setData(model->index(0,0,lastIdx),datetime.date().year());
                                              model->setData(model->index(1,0,lastIdx),datetime.date().month());
                                              model->setData(model->index(2,0,lastIdx),datetime.date().day());
                                              model->setData(model->index(3,0,lastIdx),datetime.time().hour());
                                              model->setData(model->index(4,0,lastIdx),datetime.time().minute());
                                              model->setData(model->index(5,0,lastIdx),datetime.time().second());
                                              model->setData(model->index(6,0,lastIdx),view->locale().toString(datetime.date(),QStringLiteral("dddd")));
                                          });
                                      }
                                  private:
                                      QTreeView* view;
                                      QDateTimeEdit *editor;
                                      QPersistentModelIndex lastIdx;
                                  };
                                  
                                  int main(int argc, char **argv)
                                  {
                                      QApplication app(argc,argv);
                                      ExampleWid wid;
                                      wid.show();
                                      return app.exec();
                                  }
                                  

                                  "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                  ~Napoleon Bonaparte

                                  On a crusade to banish setIndexWidget() from the holy land of Qt

                                  C 1 Reply Last reply 14 Jun 2019, 09:36
                                  0
                                  • V VRonin
                                    13 Jun 2019, 18:13

                                    Something like this minimal example is what you want or did I miss something?

                                    #include <QApplication>
                                    #include <QTreeWidget>
                                    #include <QVBoxLayout>
                                    #include <QDateTimeEdit>
                                    #include <QStandardItemModel>
                                    class ExampleWid : public QWidget{
                                        //Q_OBJECT
                                        Q_DISABLE_COPY(ExampleWid)
                                    public:
                                        explicit ExampleWid(QWidget *parent = Q_NULLPTR)
                                            :QWidget(parent)
                                            ,view(new QTreeView(this))
                                            ,editor(new QDateTimeEdit(this))
                                        {
                                            QAbstractItemModel* model = new QStandardItemModel(this);
                                            model->insertColumn(0);
                                            model->insertRows(0,2);
                                            QModelIndex parIdx= model->index(0,0);
                                            model->setData(parIdx,QStringLiteral("Parent A"));
                                            model->insertColumn(0,parIdx);
                                            model->insertRows(0,7,parIdx);
                                            model->setData(model->index(0,0,parIdx),2019);
                                            model->setData(model->index(1,0,parIdx),12);
                                            model->setData(model->index(2,0,parIdx),25);
                                            model->setData(model->index(3,0,parIdx),13);
                                            model->setData(model->index(4,0,parIdx),58);
                                            model->setData(model->index(5,0,parIdx),15);
                                            model->setData(model->index(6,0,parIdx),QStringLiteral("Wednesday"));
                                            parIdx= model->index(1,0);
                                            model->setData(parIdx,QStringLiteral("Parent B"));
                                            model->insertColumn(0,parIdx);
                                            model->insertRows(0,7,parIdx);
                                            model->setData(model->index(0,0,parIdx),2019);
                                            model->setData(model->index(1,0,parIdx),5);
                                            model->setData(model->index(2,0,parIdx),30);
                                            model->setData(model->index(3,0,parIdx),20);
                                            model->setData(model->index(4,0,parIdx),30);
                                            model->setData(model->index(5,0,parIdx),55);
                                            model->setData(model->index(6,0,parIdx),QStringLiteral("Thursday"));
                                    
                                            view->setModel(model);
                                            QVBoxLayout* minLay = new QVBoxLayout(this);
                                            minLay->addWidget(editor);
                                            minLay->addWidget(view);
                                            QObject::connect(view->selectionModel(),&QItemSelectionModel::currentChanged,this,[this](QModelIndex idx)->void{
                                                if(!idx.isValid())
                                                    return;
                                                while(idx.parent().isValid())
                                                    idx =idx.parent();
                                                lastIdx = QPersistentModelIndex();
                                                editor->setDateTime(QDateTime(
                                                    QDate(
                                                        idx.model()->index(0,0,idx).data().toInt()
                                                        ,idx.model()->index(1,0,idx).data().toInt()
                                                        ,idx.model()->index(2,0,idx).data().toInt()
                                                    )
                                                    , QTime(
                                                        idx.model()->index(3,0,idx).data().toInt()
                                                        ,idx.model()->index(4,0,idx).data().toInt()
                                                        ,idx.model()->index(5,0,idx).data().toInt()
                                                    )
                                                ));
                                                lastIdx = idx;
                                            });
                                            QObject::connect(editor,&QDateTimeEdit::dateTimeChanged,this,[this](const QDateTime &datetime)->void {
                                                if(!lastIdx.isValid())
                                                    return;
                                                QAbstractItemModel * model = view->model();
                                                model->setData(model->index(0,0,lastIdx),datetime.date().year());
                                                model->setData(model->index(1,0,lastIdx),datetime.date().month());
                                                model->setData(model->index(2,0,lastIdx),datetime.date().day());
                                                model->setData(model->index(3,0,lastIdx),datetime.time().hour());
                                                model->setData(model->index(4,0,lastIdx),datetime.time().minute());
                                                model->setData(model->index(5,0,lastIdx),datetime.time().second());
                                                model->setData(model->index(6,0,lastIdx),view->locale().toString(datetime.date(),QStringLiteral("dddd")));
                                            });
                                        }
                                    private:
                                        QTreeView* view;
                                        QDateTimeEdit *editor;
                                        QPersistentModelIndex lastIdx;
                                    };
                                    
                                    int main(int argc, char **argv)
                                    {
                                        QApplication app(argc,argv);
                                        ExampleWid wid;
                                        wid.show();
                                        return app.exec();
                                    }
                                    
                                    C Offline
                                    C Offline
                                    chakry
                                    wrote on 14 Jun 2019, 09:36 last edited by
                                    #18

                                    @VRonin said in Need help from QT Experts ( Model / View for QDateTimeEdit widget):

                                    view

                                    HI VRonin,

                                    Thank you for your reply. This would work but my model is not a local one , it is set from a different class using a set-model function(example). I need it because the model might change during run time. in this case i need dynamic signal slot right ?. I have a requirement of sessions in my program if a session is changed then the model changes which i have to set it externally.

                                    Thanks and regards

                                    1 Reply Last reply
                                    0
                                    • V Offline
                                      V Offline
                                      VRonin
                                      wrote on 14 Jun 2019, 09:46 last edited by VRonin
                                      #19

                                      Nothing difficult, mine was just an example, just remove everything in the constructor before QVBoxLayout* minLay = new QVBoxLayout(this); and add a public void setModel(QAbstractItemModel* model){view->setModel(model);} that you can use to set a new model from outside this class. Everything else is all the same

                                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                                      ~Napoleon Bonaparte

                                      On a crusade to banish setIndexWidget() from the holy land of Qt

                                      1 Reply Last reply
                                      1
                                      • T tajny_agent
                                        13 Jun 2019, 17:20

                                        You can use QDataWidgetMapper with custom delegate.

                                        void MyDelegate::setEditorData(QWidget* parent, const QModelIndex& index) const
                                        {
                                          if (auto dte = qobject_cast<QDateTimeEdit*>(editor); dte) {
                                            auto* model = index.model();
                                            const auto& year = model->index(0, 0, index.parent()).data().toString();
                                            const auto& month = model->index(1, 0, index.parent()).data().toString();
                                            // ...
                                            QDateTime dt = QDateTime::fromString(/*combine above to QDateTime*/);
                                            dte->setDateTime(dt);
                                          }
                                        }
                                        

                                        Then map your QDateTimeEdit with QDataWidgetMapper, set delegate. and voila

                                        C Offline
                                        C Offline
                                        chakry
                                        wrote on 14 Jun 2019, 09:57 last edited by
                                        #20

                                        Yes i tried that but when the model data is changed then the signal is not fired , it never comes to this function . why is that ?

                                        QObject::connect(lView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](QModelIndex idx) -> void {
                                        	qDebug() << "modelchanged " << idx;
                                            }
                                        
                                        J 1 Reply Last reply 14 Jun 2019, 10:29
                                        0
                                        • C chakry
                                          14 Jun 2019, 09:57

                                          Yes i tried that but when the model data is changed then the signal is not fired , it never comes to this function . why is that ?

                                          QObject::connect(lView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](QModelIndex idx) -> void {
                                          	qDebug() << "modelchanged " << idx;
                                              }
                                          
                                          J Offline
                                          J Offline
                                          JonB
                                          wrote on 14 Jun 2019, 10:29 last edited by
                                          #21

                                          @chakry

                                          I need it because the model might change during run time

                                          Do you mean the whole model is changed, or just one item? If it's the former:
                                          https://doc.qt.io/qt-5/qitemselectionmodel.html#currentChanged

                                          Note that this signal will not be emitted when the item model is reset.

                                          and you might mean:
                                          https://doc.qt.io/qt-5/qitemselectionmodel.html#modelChanged

                                          This signal is emitted when the model is successfully set with setModel().

                                          or am I grasping the wrong end of the stick for what you are saying?

                                          C 1 Reply Last reply 14 Jun 2019, 11:05
                                          0

                                          11/27

                                          12 Jun 2019, 16:37

                                          • Login

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