Stop QTableView from scrolling as data is added above current position(当数据添加到当前位置上方时停止 QTableView 滚动)
问题描述
我有一个简单的 QTableView,带有一个 QSortFilterProxyModel 和一个从 QAbstractTableModel 继承的自定义 TableModel 子类的源模型.该模型使用附加行动态更新.
I have a simple QTableView with a QSortFilterProxyModel and a source model of a custom TableModel subclass that inherits from QAbstractTableModel. The model is dynamically updated with additional rows.
我的问题是:如果我按列对表格进行排序,然后滚动到特定行,然后在该行上方添加更多行,则会将该行向下推.数据输入的速度足够快,以至于很难在光标下方的行发生变化的情况下单击行进行编辑.
My problem is this: If I sort the table on a column, then scroll to a specific row, and then more rows are added above this row it pushes the row down. Data is coming in fast enough that it makes it difficult to click on rows to edit them without the row changing underneath my cursor.
有没有办法阻止表格滚动并保持表格相对于选定行的位置?
Is there a way to stop the table from scrolling and maintain the position of the table relative to say a selected row?
推荐答案
QTableView::rowViewportPosition()
可用于获取当前视口位置,如果之前插入了某些内容,则必须更正该位置当前索引.
QTableView::rowViewportPosition()
can be used to get the current view port position which has to be corrected if something is inserted before current index.
可以使用信号处理程序在插入行之前和之后检索它.
It can be retrieved before and after insertion of a row using signal handlers.
因此,插入后可以在信号处理程序中相应地调整滚动.这是通过更改垂直滚动条的值来完成的.(垂直滚动模式更改为QTableView::ScrollPerPixel
以确保正确的垂直调整.)
Thus, the scrolling can be adjusted accordingly in the signal handler after the insertion. This is done changing the value of the vertical scrollbar. (The vertical scroll mode is changed to QTableView::ScrollPerPixel
to ensure correct vertical adjustment.)
一个最小的代码示例:
#include <iostream>
#include <QApplication>
#include <QMainWindow>
#include <QScrollBar>
#include <QStandardItemModel>
#include <QTableView>
#include <QTimer>
enum { NCols = 2 }; // number of columns
enum { Interval = 1000 }; // interval of auto action
enum { NRep = 5 }; // how often selected auto action is repeated
// fills a table model with sample data
void populate(QStandardItemModel &tblModel, bool prepend)
{
int row = tblModel.rowCount();
if (prepend) tblModel.insertRow(0);
for (int col = 0; col < NCols; ++col) {
QStandardItem *pItem = new QStandardItem(QString("row %0, col %1").arg(row).arg(col));
tblModel.setItem(prepend ? 0 : row, col, pItem);
}
}
// does some auto action
void timeout(QTimer &timer, QStandardItemModel &tblModel)
{
static int step = 0;
++step;
std::cout << "step: " << step << std::endl;
switch (step / NRep % 3) {
case 0: break; // pause
case 1: populate(tblModel, false); break; // append
case 2: populate(tblModel, true); break; // prepend
}
}
// managing the non-scrolling when something is inserted.
struct NoScrCtxt {
QTableView &tblView;
int y;
NoScrCtxt(QTableView &tblView_): tblView(tblView_) { }
void rowsAboutToBeInserted()
{
y = tblView.rowViewportPosition(tblView.currentIndex().row());
}
void rowsInserted()
{
int yNew = tblView.rowViewportPosition(tblView.currentIndex().row());
if (y != yNew) {
if (QScrollBar *pScrBar = tblView.verticalScrollBar()) {
pScrBar->setValue(pScrBar->value() + yNew - y);
}
}
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
// build some GUI
QMainWindow win;
QStandardItemModel tblModel(0, NCols);
for (int i = 0; i < 10; ++i) populate(tblModel, false);
QTableView tblView;
tblView.setVerticalScrollMode(QTableView::ScrollPerPixel);
tblView.setModel(&tblModel);
win.setCentralWidget(&tblView);
win.show();
// setup a "no-scroll manager"
NoScrCtxt ctxt(tblView);
QObject::connect(&tblModel, &QStandardItemModel::rowsAboutToBeInserted,
[&ctxt](const QModelIndex&, int, int) { ctxt.rowsAboutToBeInserted(); });
QObject::connect(&tblModel, &QStandardItemModel::rowsInserted,
[&ctxt](const QModelIndex&, int, int) { ctxt.rowsInserted(); });
// initiate some auto action
QTimer timer;
timer.setInterval(Interval); // ms
QObject::connect(&timer, &QTimer::timeout,
[&timer, &tblModel]() { timeout(timer, tblModel); });
timer.start();
// exec. application
return app.exec();
}
我在 Windows 10、VS2013、Qt 5.7 中编译并测试了这个:
I compiled and tested this in Windows 10, VS2013, Qt 5.7:
这篇关于当数据添加到当前位置上方时停止 QTableView 滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:当数据添加到当前位置上方时停止 QTableView 滚动


基础教程推荐
- C++,'if' 表达式中的变量声明 2021-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- 设计字符串本地化的最佳方法 2022-01-01
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01