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)
Forum Updated to NodeBB v4.3 + New Features

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.9k 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.
  • chakryC chakry

    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?

    VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on 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

    chakryC 1 Reply Last reply
    0
    • VRoninV VRonin

      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();
      }
      
      chakryC Offline
      chakryC Offline
      chakry
      wrote on 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
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on 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

          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

          chakryC Offline
          chakryC Offline
          chakry
          wrote on 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;
              }
          
          JonBJ 1 Reply Last reply
          0
          • chakryC chakry

            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;
                }
            
            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on 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?

            chakryC 1 Reply Last reply
            0
            • JonBJ JonB

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

              chakryC Offline
              chakryC Offline
              chakry
              wrote on last edited by chakry
              #22

              @JonB Thank you .
              sorry i want to correct few things . Your code is working fine with view and set model i have just verified that. The reason it didnt work was i was not displaying my view.
              I must not show view to user . i just have to map the model to widget(QDateTimeEdit) and show that widget to user. I thought with view it might work if i dont show this to user. just set everything but not showing. This dont work right? please correct me.

              I meant both cases. in one case , one child value will be changed in another case a new model is set.I can connect these signals as you mentioned but they work with TreeView when visible right?

              VRoninV 1 Reply Last reply
              0
              • chakryC chakry

                @JonB Thank you .
                sorry i want to correct few things . Your code is working fine with view and set model i have just verified that. The reason it didnt work was i was not displaying my view.
                I must not show view to user . i just have to map the model to widget(QDateTimeEdit) and show that widget to user. I thought with view it might work if i dont show this to user. just set everything but not showing. This dont work right? please correct me.

                I meant both cases. in one case , one child value will be changed in another case a new model is set.I can connect these signals as you mentioned but they work with TreeView when visible right?

                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #23

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

                The reason it didnt work was i was not displaying my view.
                I must not show view to user . i just have to map the model to widget

                So how do you decide what parent item of the model should be edited in the widget?

                "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

                chakryC 1 Reply Last reply
                0
                • VRoninV VRonin

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

                  The reason it didnt work was i was not displaying my view.
                  I must not show view to user . i just have to map the model to widget

                  So how do you decide what parent item of the model should be edited in the widget?

                  chakryC Offline
                  chakryC Offline
                  chakry
                  wrote on last edited by
                  #24

                  @VRonin parent has a name , which is fixed. I will find it based on the name. The respective Model index is used unless a new model is updated.

                  just a bit more explanation to be clear. I have a tree model and all these elements/children in tree model should be shown in view as a widget easily editable( ex: text box, checkbox, combobox, spinbox ..etc) . These standard items are working using widget mapper. I search for a parent and map its model index to one of the these standard widgets. In this model i also have 6 children's having date ,time info. I wanted to map these 6 children's to a single widget datetimeedit. This was my main issue . This is not possible with restriction on datawidgetmapper ( only one property can be mapped ).

                  thanks and regards.

                  VRoninV 1 Reply Last reply
                  0
                  • chakryC chakry

                    @VRonin parent has a name , which is fixed. I will find it based on the name. The respective Model index is used unless a new model is updated.

                    just a bit more explanation to be clear. I have a tree model and all these elements/children in tree model should be shown in view as a widget easily editable( ex: text box, checkbox, combobox, spinbox ..etc) . These standard items are working using widget mapper. I search for a parent and map its model index to one of the these standard widgets. In this model i also have 6 children's having date ,time info. I wanted to map these 6 children's to a single widget datetimeedit. This was my main issue . This is not possible with restriction on datawidgetmapper ( only one property can be mapped ).

                    thanks and regards.

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #25

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

                    I wanted to map these 6 children's to a single widget datetimeedit. This was my main issue . This is not possible with restriction on datawidgetmapper ( only one property can be mapped ).

                    This is what the code in my 2 connect do:
                    This puts an index inside the QDatetimeEdit

                    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;
                    

                    This puts the data from the QDatetimeEdit back into the model

                    if(!lastIdx.isValid())
                                    return;
                                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")));
                    

                    "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

                    chakryC 1 Reply Last reply
                    0
                    • VRoninV VRonin

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

                      I wanted to map these 6 children's to a single widget datetimeedit. This was my main issue . This is not possible with restriction on datawidgetmapper ( only one property can be mapped ).

                      This is what the code in my 2 connect do:
                      This puts an index inside the QDatetimeEdit

                      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;
                      

                      This puts the data from the QDatetimeEdit back into the model

                      if(!lastIdx.isValid())
                                      return;
                                  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")));
                      
                      chakryC Offline
                      chakryC Offline
                      chakry
                      wrote on last edited by chakry
                      #26

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

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

                      I wanted to map these 6 children's to a single widget datetimeedit. This was my main issue . This is not possible with restriction on datawidgetmapper ( only one property can be mapped ).

                      Thank you VRonin for helping
                      This is what the code in my 2 connect do:
                      This puts an index inside the QDatetimeEdit ```
                      ( Its true but where should i add this code , view and selectionmodel as you mentioned before doesnot work as there is no view in my case , any suggestion where to keep this )

                      > ```cpp
                      > 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;
                      > ```
                      > 
                      > This puts the data from the `QDatetimeEdit` back into the model  ```
                      **( This works as in this case i use dateTimechanged from QDateTimeEditsignal and set the passed model data)**
                      
                      if(!lastIdx.isValid())
                                      return;
                                  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")));
                      
                      1 Reply Last reply
                      0
                      • VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by VRonin
                        #27

                        Can you reformat the answer? it's difficult to follow...

                        "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

                        • Login

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