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)
QtWS25 Last Chance

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.
  • chakryC Offline
    chakryC Offline
    chakry
    wrote on last edited by chakry
    #1

    I have a Tree Model ( Parent A has 6 childs )
    Child 1 : stores date information
    Child 2 : stores time information
    Child 3 : stores day information
    Child 4 : stores hour information
    Child 5 : stores minute information
    Child 6 : stores sec information

    I want to place a widget (QDateTimeEdit) and connect it to the tree model.

    I have tried these things but not succeeded:

    1. Data widget mapper ( works only with one section to widget , i can map only one child and one property)

    2. QComboboxWidget ( SetDelegate and have a set editor and set model data )

    QComboboxWidget* cbx = new QComboboxWidget;

    cbx->setmodel(mymodel); // mymodel has a parent and 6 children and it just adds all children as a list of elements

    i wanted to see 2019:06:10 15:12:25 on my widget and if i change any of this value then it also updates to my model children

    its taking so much time for a special widget where as a lineedit/checkbox/combobox using 1 to 1 data widget mapper is working easy and perfectly. Please help me out

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by SGaist
      #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

      JonBJ 1 Reply Last reply
      2
      • SGaistS SGaist

        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]

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #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
        • chakryC Offline
          chakryC Offline
          chakry
          wrote on 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.

          JonBJ 1 Reply Last reply
          0
          • chakryC chakry

            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.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on 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
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on 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

              JonBJ 1 Reply Last reply
              2
              • SGaistS SGaist

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

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #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
                • chakryC Offline
                  chakryC Offline
                  chakry
                  wrote on last edited by chakry
                  #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
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 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

                    chakryC 1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on 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

                      chakryC 2 Replies Last reply
                      4
                      • SGaistS SGaist

                        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.

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

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

                        1 Reply Last reply
                        0
                        • SGaistS SGaist

                          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.

                          chakryC Offline
                          chakryC Offline
                          chakry
                          wrote on 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
                          • VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by VRonin
                            #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
                            • chakryC Offline
                              chakryC Offline
                              chakry
                              wrote on 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?

                              VRoninV 1 Reply Last reply
                              0
                              • SGaistS SGaist

                                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.

                                chakryC Offline
                                chakryC Offline
                                chakry
                                wrote on 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 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

                                  chakryC 1 Reply Last reply
                                  0
                                  • 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

                                          • Login

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