获取QListView中所有可见项目的简单方法



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

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

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

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

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

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

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

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

定时器的timeout()信号将连接到webcletic所讨论的插槽。这样,如果用户快速向下滚动,则只有最后的项目才会更新。一般情况下,它会更新任何超过300毫秒的可见内容!

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

尽管这在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私有标头,因此在后一版本中可能不再工作,需要进行一些更改。

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

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

如果你只需要知道一个项目是否可见,你可以在视图中增加帧数->paintEvent,并在代理项中设置该数字。如果项目与当前帧编号匹配,则该项目可见。

如果需要所有可见项目的列表,请清除视图中的可见项目列表->paintEvent,并将每个项目添加到int the delegate中->paintEvent添加到可见项目列表中。

最新更新