0

I have subclassed QAbstractItemModel and trying to retrieve a widget in slot of dataChanged signal.

connect(model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(slotDataChanged(const QModelIndex&, const QModelIndex&)));

void MyEditor::slotDataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight)
{
    QComboBox* widget = dynamic_cast<QComboBox*>(sender());
    if (widget)
    {
         // do something
    }
}

Here I am getting a null widget everytime, same result with qobject_cast.

I am setting combobox widget in my tableview a delegate class which derives QStyledItemDelegate.

MyDelegate* myDelegate;
myDelegate = new MyDelegate();
tableView->setItemDelegate(myDelegate);
tableView->setModel(model);


 QWidget* MyDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const
 {
      QComboBox* cb = new QComboBox(parent);
      cb->addItem(QString("All"));
      cb->setCurrentIndex(0);
      return cb;
 }

How can I obtain sender object in this case? Thanks.

wazza
  • 313
  • 3
  • 19
  • 4
    [`dataChanged()`](https://doc.qt.io/qt-5/qabstractitemmodel.html#dataChanged) is emitted from the model (since it is one of `QAbstractItemModel`'s signals). It is **not** emitted the editor widget. what makes you think it would be emitted from there? You can only cast the `sender()` to a `QAbstractItemModel`. – Mike Nov 22 '16 at 16:53
  • 1
    You should also be using `qobject_cast`, not `dynamic_cast` on `QObject`: it will be quicker, and it will work without RTTI as well. – Kuba hasn't forgotten Monica Nov 22 '16 at 18:12
  • Anyhow use qobject_cast to resolve QObject derived pointer. – Alexander V Nov 22 '16 at 21:23
  • Can you show a bit broader what you want to achieve? Why do you need to access the editor widget after the data was already updated in the model? – Dusteh Nov 22 '16 at 21:35
  • @Mike Yeah I know dataChanged() signal is emitted from the model. I have emitted it explicitly whenever some data is changed in my model to notify view. I have observed that whenever I was double clicking on any cell in my editor, same signal is emitted and I was try to handle few thing in it's slot by obtaining the widget on which user has double clicked. Anyways I have achieved it. Thanks. – wazza Nov 23 '16 at 06:07

2 Answers2

1

Not sure of what are your intentions. Acquiring the editor widget when the data is already updated in the model is unnecessary in general. Seems to me that a brief introduction to Model-View-Delegate concept is needed to solve your problem.

In short, the view, which in your case is the QTableView, has no data by itself. View acquires data from the attached model by calling data method. When user tries to edit some data, delegate createEditor and setEditorData methods are called. The latter has model pointer as one of the arguments so it can access actual data which needs to be represented.

When user finishes editing setModelData is called which has the editor widget available to acquire the updated value. It also has the model available to change the proper data entry normally done via setData method. At this point the dataChanged signal is emitted which notifies the view that corresponding data was updated so it can refresh the displayed value(s).

Hence, try rethinking your design. Maybe what you want to achieve can be implemented differently or your implementation can be slightly modified to conform the described flow.

You can also check the Qt site for Star Delegate Example to see some sample implementations or Model View Tutorial for a broader description of the Model-View topic.

Dusteh
  • 1,496
  • 16
  • 21
  • Thanks for pointing me in right direction. My model/view design is fine, I have learned from above mentioned tutorial only. It was a fairly simple problem and now I have solved it. Can you please help me with this question, I am struggling from quite a time on this question: http://stackoverflow.com/questions/40724282/tooltip-is-not-updated-on-moving-from-one-row-to-another – wazza Nov 23 '16 at 06:43
0

My Model/View design was fine. I just needed to obtain a widget when user double clicks on a cell in my editor.

QComboBox* widget = dynamic_cast<QComboBox*>(tableView->indexWidget(topLeft));
if (widget)
{
    // Do something
}

Here in slotDataChanged I obtained the required widget using QModelIndex. Thanks for helping me out.

wazza
  • 313
  • 3
  • 19