4

我正在尝试使用 Qt 框架开发一个图片库应用程序。应用程序从所选文件夹加载所有图像,并使用 QListView 控件显示这些图像。但现在我想通过仅加载用户可见的图像来减少内存消耗。由于没有直接功能可以获取视图中的所有可见项目,因此我无法实现这一点。

4

5 回答 5

5

indexAt您可以使用该函数获取列表视图的可见项。有关更多详细信息和示例,您可以查看以下文章:

http://qt-project.org/faq/answer/how_can_i_get_hold_of_all_of_the_visible_items_in_my_qlistview

于 2012-03-22T08:02:36.763 回答
2

我找到了!您必须将列表小部件的垂直滚动条连接到信号:

connect(ui->listWidget->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(launch_timer()));

每次用户滚动时,都会省略 valuechanged(int) 信号!问题是你不应该在每次listwidget的垂直滚动条的值发生变化时运行webclectic在这个问题中提供的代码,因为在这么短的时间内运行这么多代码,程序将无响应。

因此,您必须有一个单次计时器并将其指向上面 webclectic 发布的功能。调用 launch_timer() 时,您执行以下操作:

  if(timer->isActive()){
     timer->stop();
     timer->start(300);
   }
   else
      timer->start(300);

定时器的 timeout() 信号将连接到 webclectic 所说的 slot。这样,如果用户一直快速向下滚动,则只会更新最后的项目。一般来说,它会更新任何可见的时间超过 300 毫秒!

于 2012-08-19T08:44:11.977 回答
0

我认为您需要实现自己的模型(查看 QAbstractListModel 文档),这样您就可以决定何时必须加载更多图像以显示并释放一些变得不可见的图像。

于 2012-08-19T07:56:41.523 回答
0

虽然这不是那么简单,Qt 4但在下面复制总是很简单:

#include <private/qlistview_p.h>

class QListViewHelper : public QListView
{
    typedef QListView super;
    inline QListViewHelper() {} //not intended to be constructed
public:
    inline static QVector<QModelIndex> indexFromRect(const QListView *view,
                                                                 const QRect &rect)
    {
        const QListViewPrivate *d = static_cast<const QListViewPrivate *>(QObjectPrivate::get(view)); //to access "QListViewPrivate::intersectingSet(...)"
        const QListViewHelper *helper = static_cast<const QListViewHelper *>(view); //to access "QListView::horizontalOffset()"
        return d->intersectingSet(rect.translated(helper->horizontalOffset(), helper->verticalOffset()), false);
    }
    inline static QVector<QModelIndex> visibleItems(const QListView *view)
        { return indexFromRect(view, view->rect()); }

    inline static QModelIndex firstVisible(const QListView *view)
        { return visibleItems(view).value(0); }
    inline static QModelIndex lastVisible(const QListView *view) {
        const QVector<QModelIndex> &items = visibleItems(view);
        return items.value(items.count() - 1);
    }
};

void ourTest(const QListView *view) {
    QModelIndex &index = QListViewHelper::firstVisible(view);
    qDebug("QListViewHelper: first visible row is %d", index.row());

    index = QListViewHelper::lastVisible(view);
    qDebug("QListViewHelper: last visible row is %d", index.row());
}

用法: QModelIndex &index = QListViewHelper::firstVisible(listViewPointerHere)

注意:因为它确实使用Qt 4.8私有头文件,所以它可能不再在以后的版本中工作,需要进行一些更改。

于 2018-11-14T11:03:39.713 回答
0

您可以跟踪每个绘制事件绘制的所有元素。我使用了一个委托并重载了绘制事件。

我还重载了视图中的绘制事件。在此调用期间,所有可见的代表都将获得一个绘制事件。

如果您只需要知道某个项目是否可见,您可以在 view->paintEvent 中增加帧计数,并在委托项目中设置该数字。该项目是可见的,该项目与当前帧号匹配。

如果您需要所有可见项目的列表,请清除 view->paintEvent 中的可见项目列表,并将 int 委托->paintEvent 中的每个项目添加到可见项目列表中。

于 2022-01-27T00:07:19.687 回答