无法在 QAbstractItemModel 的 dataChanged 信号槽中获取发送者对象
Posted
技术标签:
【中文标题】无法在 QAbstractItemModel 的 dataChanged 信号槽中获取发送者对象【英文标题】:Unable to obtain sender object in slot of dataChanged signal of QAbstractItemModel 【发布时间】:2016-11-22 16:34:34 【问题描述】:我对 QAbstractItemModel 进行了子类化,并尝试在 dataChanged 信号槽中检索小部件。
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
这里我每次都得到一个空小部件,与 qobject_cast 的结果相同。
我在我的表格视图中设置组合框小部件,这是一个派生 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;
在这种情况下如何获取 sender 对象?谢谢。
【问题讨论】:
dataChanged()
从模型中发出(因为它是QAbstractItemModel
的信号之一)。它不是发出了编辑器小部件。是什么让你认为它会从那里发出?您只能将 sender()
转换为 QAbstractItemModel
。
您还应该在QObject
上使用qobject_cast
,而不是dynamic_cast
:它会更快,并且在没有RTTI 的情况下也可以工作。
无论如何使用 qobject_cast 来解析 QObject 派生的指针。
你能更广泛地展示你想要实现的目标吗?为什么在模型中的数据已经更新后还需要访问编辑器小部件?
@Mike 是的,我知道 dataChanged() 信号是从模型中发出的。每当我的模型中的某些数据发生更改以通知视图时,我都会明确地发出它。我观察到,每当我在编辑器中双击任何单元格时,都会发出相同的信号,我试图通过获取用户双击的小部件来处理它的插槽中的一些事情。反正我已经实现了。谢谢。
【参考方案1】:
不知道你的意图是什么。当模型中的数据已经更新时获取编辑器小部件通常是不必要的。
在我看来,解决您的问题需要对Model-View-Delegate
概念的简要介绍。
简而言之,在您的情况下为QTableView
的视图本身没有数据。 View 通过调用data
方法从附加模型中获取数据。当用户尝试编辑某些数据时,会调用委托 createEditor
和 setEditorData
方法。后者将模型指针作为参数之一,因此它可以访问需要表示的实际数据。
当用户完成编辑时,setModelData
被调用,它具有可用于获取更新值的编辑器小部件。它还具有可用于更改通常通过setData
方法完成的正确数据输入的模型。此时会发出 dataChanged 信号,通知视图相应的数据已更新,以便刷新显示的值。
因此,请尝试重新考虑您的设计。也许您想要实现的目标可以采用不同的方式实现,或者您的实现可以稍作修改以符合所描述的流程。
您还可以查看 Qt 站点以获取 Star Delegate Example 以查看一些示例实现,或查看 Model View Tutorial 以获取有关模型视图主题的更广泛描述。
【讨论】:
感谢您为我指明正确的方向。我的模型/视图设计很好,我只是从上面提到的教程中学到的。这是一个相当简单的问题,现在我已经解决了。你能帮我解决这个问题吗,我在这个问题上挣扎了很长时间:***.com/questions/40724282/…【参考方案2】:我的模型/视图设计很好。当用户在我的编辑器中双击一个单元格时,我只需要获取一个小部件。
QComboBox* widget = dynamic_cast<QComboBox*>(tableView->indexWidget(topLeft));
if (widget)
// Do something
在 slotDataChanged 中,我使用 QModelIndex 获得了所需的小部件。 感谢您帮助我。
【讨论】:
以上是关于无法在 QAbstractItemModel 的 dataChanged 信号槽中获取发送者对象的主要内容,如果未能解决你的问题,请参考以下文章
QAbstractItemModel::columnCount - 每行的可变列数
QAbstractItemModel - QModelIndex 对象在创建时是不是应该被缓存?
在 QAbstractItemModel 中不区分大小写排序