Моя идея - использовать QListView :: indexAt () (унаследованный от QAbstractView
), чтобы получить индекс строки для
- верхний левый угол
- нижний левый угол
окна просмотра списка и определение количества видимых элементов по их разнице.
Чтобы проверить это, я сделал MCVE testQListViewNumVisibleItems.cc
:
// Qt header:
#include <QtWidgets>
class ListWidget: public QListWidget {
public:
ListWidget(QWidget *pQParent = nullptr): QListWidget(pQParent) { }
virtual ~ListWidget() = default;
ListWidget(const ListWidget&) = delete;
ListWidget& operator=(const ListWidget&) = delete;
int getNumVisibleItems() const
{
const QSize size = viewport()->size();
const QModelIndex qMIdx0 = indexAt(QPoint(0, 0));
const QModelIndex qMIdx1 = indexAt(QPoint(0, size.height() - 1));
//qDebug() << "qMIdx0:" << qMIdx0 << "qMIdx1:" << qMIdx1;
return qMIdx0.isValid()
? (qMIdx1.isValid() ? qMIdx1.row() : count()) - qMIdx0.row()
: 0;
}
};
const int MaxItems = 20;
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
ListWidget qLst;
qLst.resize(200, 200);
qLst.show();
// timer to populate list view
using namespace std::chrono_literals;
QTimer qTimer;
qTimer.setInterval(1000ms);
// install signal handlers
int n = 0;
QObject::connect(&qTimer, &QTimer::timeout,
[&]() {
qLst.addItem(QString("item %0").arg(++n));
qDebug() << "Visible items:" << qLst.getNumVisibleItems();
if (n >= MaxItems) qTimer.stop();
});
// runtime loop
qTimer.start();
return app.exec();
}
и CMakeLists.txt
:
project(QListViewNumVisibleItems)
cmake_minimum_required(VERSION 3.10.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Qt5Widgets CONFIG REQUIRED)
include_directories("${CMAKE_SOURCE_DIR}")
add_executable(testQListViewNumVisibleItems testQListViewNumVisibleItems.cc)
target_link_libraries(testQListViewNumVisibleItems Qt5::Widgets)
построен и протестирован в VS2017 на Windows 10:
Реализовав то, что пришло мне в голову, я немного погуглил, чтобы, возможно, увидеть другие подходы. (Признаюсь, я должен был это сделать раньше.)
Таким образом, я обнаружил следующий возможный дубликат:
ИТОГО: Простой способ получить все видимые элементы в QListView
Принятый ответ не содержит ничего, кроме подсказки для indexAt
и ссылки на статью Qt-FAQ:
Как я могу получить все видимые элементы в моем QListView?
Чтобы получить видимые элементы в QListView, http://doc.qt.io/qt-5/qlistview.html, затем вы можете перебирать их, используя indexAt () http://doc.qt.io/qt-5/qlistview.html#indexAt. Вы можете получить первый видимый элемент с помощью indexAt (QPoint (0, 0)), затем, чтобы получить индекс в следующей позиции, используйте visualRect () http://doc.qt.io/qt-5/qlistview.html#visualRect, чтобы узнать, какой ваш следующий вызов itemAt () должно быть. Эта позиция была бы:
visualRect.y() + visualRect.height() + 1 effectively.
См. Иллюстрацию в следующем примере:
#include <QtGui>
QList <QModelIndex>myList;
class ListView : public QListView
{
Q_OBJECT
public:
ListView()
{
QStringListModel *myModel = new QStringListModel(this);
QStringList list;
list << "a" << "b" <<"c" <<"d" <<"e" <<"f" <<"g" <<"h" <<"i" <<"j" <<"k";
myModel->setStringList(list);
setModel(myModel);
QTimer::singleShot(3000, this, SLOT(test1()));
}
public slots:
void test1()
{
QModelIndex firstIndex = indexAt(QPoint(0, 0));
if (firstIndex.isValid()) {
myList << firstIndex;
} while (viewport()->rect().contains(QPoint(0, visualRect(firstIndex).y() + visualRect(firstIndex).height() + 1 ))) {
firstIndex = indexAt(QPoint(0, visualRect(firstIndex).y() + visualRect(firstIndex).height() + 1 ));
myList << firstIndex;
}
qDebug() << myList.count() << "are visible";
}
};
#include "main.moc"
int main(int argc, char** argv)
{
QApplication app(argc, argv);
ListView window;
window.resize(100, 50);
window.show();
return app.exec();
}
person
Scheff's Cat
schedule
03.06.2020
QAbstractView
). Применяя его к левому верхнему и левому нижнему углу, вы должны получить два индекса, по которым вы можете получить разницу. (Вероятно, есть некоторые крайние случаи, о которых вам следует позаботиться, например, если текущее представление не полностью заполнено.) - person Scheff's Cat   schedule 03.06.2020