2
votes

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?

1
You've phrased your question in a classical XY problem way: you presuppose a solution that you clearly see won't work. Instead, you should ask how to solve your original problem - namely how to cache the data for a view when the source model's data is gone. It seems like you've implemented a lot of things while chasing the incorrect solution. Please edit the question to focus on the original problem: explain how the source model loses its data, for example. Only mention your proposed solution and its woes as an aside.Kuba hasn't forgotten Monica
I hadn't realized - thanks for bringing that up.jehuty

1 Answers

1
votes

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.