問(wèn)題描述
我有一個(gè)簡(jiǎn)單的 QTableView,帶有一個(gè) QSortFilterProxyModel 和一個(gè)從 QAbstractTableModel 繼承的自定義 TableModel 子類(lèi)的源模型.該模型使用附加行動(dòng)態(tài)更新.
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.
我的問(wèn)題是:如果我按列對(duì)表格進(jìn)行排序,然后滾動(dòng)到特定行,然后在該行上方添加更多行,則會(huì)將該行向下推.數(shù)據(jù)輸入的速度足夠快,以至于很難在光標(biāo)下方的行發(fā)生變化的情況下單擊行進(jìn)行編輯.
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.
有沒(méi)有辦法阻止表格滾動(dòng)并保持表格相對(duì)于選定行的位置?
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()
可用于獲取當(dāng)前視口位置,如果之前插入了某些內(nèi)容,則必須更正該位置當(dāng)前索引.
QTableView::rowViewportPosition()
can be used to get the current view port position which has to be corrected if something is inserted before current index.
可以使用信號(hào)處理程序在插入行之前和之后檢索它.
It can be retrieved before and after insertion of a row using signal handlers.
因此,插入后可以在信號(hào)處理程序中相應(yīng)地調(diào)整滾動(dòng).這是通過(guò)更改垂直滾動(dòng)條的值來(lái)完成的.(垂直滾動(dòng)模式更改為QTableView::ScrollPerPixel
以確保正確的垂直調(diào)整.)
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.)
一個(gè)最小的代碼示例:
#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 中編譯并測(cè)試了這個(gè):
I compiled and tested this in Windows 10, VS2013, Qt 5.7:
這篇關(guān)于當(dāng)數(shù)據(jù)添加到當(dāng)前位置上方時(shí)停止 QTableView 滾動(dòng)的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!