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. Custom Widget with QDataWidgetMapper in AutoSubmit Mode.
QtWS25 Last Chance

Custom Widget with QDataWidgetMapper in AutoSubmit Mode.

Scheduled Pinned Locked Moved Unsolved General and Desktop
qdatawidgetmapp
8 Posts 2 Posters 3.4k 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.
  • M Offline
    M Offline
    mawh1960
    wrote on 15 Apr 2017, 20:16 last edited by
    #1

    Hello,

    I'm having a problem with getting a custom widget to properly update a model when the widget's value is changed (after losing focus).
    The widget is mapped to a model using QDataWidgetMapper in AutoSubmit mode.

    The widget's value is read properly from the model and written properly when the mapper's submit() method is called, however the value is not updated to the model when the widget's NOTIFY signal is fired.

    Interestingly, if I derive the widget directly from QComboBox and use the same property it works fine.

    This example is a simplified widget that exhibits the problem; In practice, the custom widgets I want to use are more complex.

    #include <QComboBox>
    
    class TestCustomWidget : public QWidget
    {
      Q_OBJECT
      Q_PROPERTY(int id READ id WRITE setId NOTIFY idChanged USER true)
    public:
      explicit TestCustomWidget(QWidget* parent=0);
    
      int id() const;
    
    public Q_SLOTS:
      void setId(const int &);
    
    Q_SIGNALS:
      void idChanged(int);
    
    protected slots:
      void onSelectionChanged(const int &);
    
    protected:
      QComboBox *m_comboBox;
      int m_id;
    };
    
    TestCustomWidget::TestCustomWidget(QWidget* parent)
      : QWidget(parent),
        m_comboBox(new QComboBox(this)),
        m_id(0)
    {
      QVBoxLayout *layout = new QVBoxLayout;
      layout->setContentsMargins(0, 0, 0, 0);
      layout->addWidget(m_comboBox);
      layout->addStretch();
      setLayout(layout);
      
      m_comboBox->addItems ( (QStringList() << "A" << "B" << "C" << "D" ) );
    
      connect(m_comboBox, SIGNAL(currentIndexChanged(int)), this ,SLOT(onSelectionChanged(int)) );
    }
    
    
    int TestCustomWidget::id() const
    {
      return m_id;
    }
      
    void TestCustomWidget::setId(const int &id)
    {
      if ( id != m_id ) {
        m_id = id;
        m_comboBox->setCurrentIndex(id/10);
        emit idChanged(m_id);
      }
    }
    
    
    void TestCustomWidget::onSelectionChanged(const int &index)
    {
      setId(index * 10);
    }
    

    In my form, the widget is mapped using the custom property, but the model's setData() method is not called when the widget value is changed after it loses focus.

    ....
      m_TestCustomWidget = new TestCustomWidget (this);
      m_mapper( new QDataWidgetMapper(this) );
      m_mapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
    
      m_mapper->addMapping(m_TestCustomWidget, 0, "id");
    ...
    
    Has anyone else ever experienced this behavior?
    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 16 Apr 2017, 19:22 last edited by
      #2

      Hi,

      An educated guess, you should check the focus in/focus out events.

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

      1 Reply Last reply
      0
      • M Offline
        M Offline
        mawh1960
        wrote on 16 Apr 2017, 23:07 last edited by
        #3

        Hi, thanks very much for your reply. I believe you are pointing me in the right direction.

        The custom widget doesn't appear to receive focus events, even after I added

        setFocusPolicy(Qt::StrongFocus);
        

        This makes sense seeing that the custom widget is only acting as a container for the ComboBox. So I guess my question is how can I get the container widget to propagate the ComboBox's focus events?

        Thanks,
        Mike

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 17 Apr 2017, 20:02 last edited by
          #4

          Check the QObject::installEventFilter.

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

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mawh1960
            wrote on 17 Apr 2017, 20:45 last edited by
            #5

            I installed an event filter on the combobox:

              m_comboBox->installEventFilter(this);
            

            And reimped eventFilter:

            bool TestCustomWidget::eventFilter(QObject *object, QEvent *event)
            {
              if (object == m_comboBox) {
                if ( event->type() == QEvent::FocusOut ) {
                  QFocusEvent *e = static_cast<QFocusEvent *>(event);
                  focusOutEvent( e );
                  return true;
                }
                else if ( event->type() == QEvent::FocusIn ) {
                  QFocusEvent *e = static_cast<QFocusEvent *>(event);
                  focusInEvent( e );
                  return true;
                }
              }
              return QWidget::eventFilter(object, event);
            }
            

            But this still doesn't fire whatever mechanism is behind the mapper to commit the data to the model.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 18 Apr 2017, 20:42 last edited by
              #6

              I was rather thinking of mimicking what's done by QComboBox. AFAICS you are only intercepting all the events and rather execute the one from your own widget which doesn't do anything special.

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

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mawh1960
                wrote on 21 Apr 2017, 05:39 last edited by
                #7

                Sorry, but I don't understand what you are suggesting.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 21 Apr 2017, 07:01 last edited by
                  #8

                  I'm suggesting to take a look at the implementation of QComboBox to see what the focus related methods are doing and then adapt that to your widget.

                  Basically, your event filter is just eating the focus events from your QComboBox.

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

                  1 Reply Last reply
                  0

                  4/8

                  17 Apr 2017, 20:02

                  • Login

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