gpt4 book ai didi

c++ - 当数据添加到当前位置上方时停止 QTableView 滚动

转载 作者:搜寻专家 更新时间:2023-10-31 01:32:51 24 4
gpt4 key购买 nike

我有一个带有 QSortFilterProxyModel 的简单 QTableView 和一个继承自 QAbstractTableModel 的自定义 TableModel 子类的源模型。该模型会使用其他行动态更新。

我的问题是:如果我按列对表进行排序,然后滚动到特定行,然后在该行上方添加更多行,它会将行向下推。数据传入的速度足够快,以至于在光标下方的行不发生变化的情况下,很难单击行来编辑它们。

有没有办法阻止表格滚动并保持表格相对于选定行的位置?

最佳答案

QTableView::rowViewportPosition() 可用于获取当前视口(viewport)位置,如果在当前索引之前插入某些内容,则必须更正该位置。

可以使用信号处理程序在插入行之前和之后检索它。

因此,插入后可以在信号处理程序中相应地调整滚动。这是通过更改垂直滚动条的值完成的。 (垂直滚动模式更改为 QTableView::ScrollPerPixel 以确保正确的垂直调整。)

一个最小的代码示例:

#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 中编译和测试了这个:

Snapshot of sample application

关于c++ - 当数据添加到当前位置上方时停止 QTableView 滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42448836/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com