jehuty
jehuty

Reputation: 538

Disconnect slot from parent class QAbstractItemView

My SuperTable class inherits from QTableView, who, in turn, inherits from QAbstractItemView.

At some point, the QTableView's QScrollBar emits a signal that triggers the QAbstractItemView::verticalScrollbarValueChanged(int) slot.

For my application, it's important this doesn't happen, so I'd like to disconnect that slot in QAbstractItemView, but I haven't been able to find a way to gain access to it from SuperTable.

edit/

What I'm trying to achieve: the table model's data is no longer available, but I want to keep the dialog with the QTableView and the data it already contains, available. But I can't have its data() method be called, because I don't have anything to return anymore. For the most part, I've accomplished this, with one big exception: whenever the table is scrolled with the mouse over the cells, the following happens:

myApp::SuperTable::data(QModelIndex const&, int) const
QSortFilterProxyModel::data(QModelIndex const&, int) const
QAbstractItemViewPrivate::checkMouseMove(QPersistentModelIndex const&) QAbstractItemView::verticalScrollbarValueChanged(int)
QMetaObject::activate(QObject*, QMetaObject const*, int, void**)
QAbstractSlider::valueChanged(int)

/edit

More specifically, peeking at Qt's implementation of qabstractitemview.cpp, this is the connection I'd like to disconnect:

void QAbstractItemViewPrivate::init()
{
    // (...)
    QObject::connect(vbar, SIGNAL(valueChanged(int)),
                     q, SLOT(verticalScrollbarValueChanged(int)));
    // (...)
}

Since it's on the private side of things, unsure whether this is even possible. Is there a way?

Upvotes: 2

Views: 161

Answers (1)

If the model's data is gone, then it's gone, and it's the view's job to notify the user of that fact.

If you don't want the data to be gone, then make it stay instead of lying to the view. The view can request model's data at any time, and your dependence on the view somehow being quiescent "if only" scrollbars don't move is incorrect. There's no contract between the view and the model that guarantees such behavior.

The correct approach is to insert a caching proxy viewmodel between the model and the view. When the source model indicates that it has no data anymore (it might signal a reset or indicate that all rows were removed), the proxy would limit its own data to a certain most recently cached contiguous group of rows, perhaps querying the view about visible rows. You'd want one proxy per view, of course.

Also note that if you've implemented your own model that doesn't indicate being empty, but somehow returns different values from data (or crashes!) without emitting relevant signals - you've already broken things beyond repair. The model's state, as visible to any external observer, must be consistent.

Upvotes: 1

Related Questions