c - Qt C++ ListView使用QAbstractItemModel追加数据定位不准确
问题描述
使用自定义数据模型,如果当前浏览位置超过100个,添加数据后会定位到第100个位置;
列表模型:
header:
#include <QAbstractListModel>
class ChatListItemModal: public QAbstractListModel {
Q_OBJECT
public:
explicit ChatListItemModal(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
void addChatItems(QVector<QString> items);
private:
QVector<QString> chatItem;
};
cpp:
#include "chatlistitemmodel.h"
ChatListItemModal::ChatListItemModal(QObject *parent): QAbstractListModel(parent)
{
}
int ChatListItemModal::rowCount(const QModelIndex &parent) const
{
return (parent.isValid() && parent.column() != 0) ? 0 : this->chatItem.size();
}
QVariant ChatListItemModal::data(const QModelIndex &index, int role) const {
if (index.isValid() && index.row() < chatItem.size() && index.row() >= 0 && role == Qt::DisplayRole)
return QVariant::fromValue<QString>(chatItem.at(index.row()));
return QVariant();
}
void ChatListItemModal::addChatItems(QVector<QString> items)
{
if (items.isEmpty())
return;
beginInsertRows(QModelIndex(),
chatItem.size(),
chatItem.size() + items.size() - 1
);
chatItem.append(items);
endInsertRows();
}
QScrollView:
header :
#include "chatlistitemdelegate.h"
#include "chatlistitemmodel.h"
#include <QListView>
#include <QVector>
class ChatListScrollView: public QListView
{
Q_OBJECT
public:
ChatListScrollView(QWidget *parent = nullptr);
void render();
void onAddChat(const int count = 0);
private:
ChatListItemModal *listModal;
ChatListItemDelegate *listItemDelegate;
};
cpp:
#include "chatlistscrollview.h"
ChatListScrollView::ChatListScrollView(QWidget *parent): QListView(parent)
{
render();
}
void ChatListScrollView::render()
{
setFrameShape(QListView::NoFrame);
setResizeMode(QListView::ResizeMode::Fixed);
setLayoutMode(QListView::LayoutMode::Batched);
setFlow(QListView::TopToBottom);
setMovement(QListView::Static);
setViewMode(QListView::ListMode);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
setAutoScroll(true);
setUniformItemSizes(true);
viewport()->setAutoFillBackground(false);
listItemDelegate = new ChatListItemDelegate(this);
setItemDelegate(listItemDelegate);
listModal = new ChatListItemModal(this);
setModel(listModal);
scrollToBottom();
}
// parent component trigger
void ChatListScrollView::onAddChat(const int count)
{
int dataCount = listModal->rowCount();
QVector<QString> list;
for (int i = 0; i < count; ++i)
{
QString title = QStringLiteral("hello %1").arg(i + dataCount);
list.push_back(title);
}
listModal->addChatItems(list);
}
感觉好像没有调用其他方法,data()中的输出好像是先拿到第100行的数据,然后再拿到剩下的数据。
感谢您的任何建议!
解决方案
我虽然更像是一个真正的最小的、可编译的例子——它对我来说很好用:
class ChatListItemModel : public QAbstractListModel
{
public:
int rowCount(const QModelIndex &) const override { return m_chatItem.count(); }
QVariant data(const QModelIndex &index, int role) const override {
if (index.isValid() && index.row() < m_chatItem.size() && index.row() >= 0 && role == Qt::DisplayRole)
return m_chatItem.at(index.row());
return QVariant();
}
void addChatItems(const QVector<QString> &items)
{
if (items.isEmpty())
return;
beginInsertRows(QModelIndex(),
m_chatItem.size(),
m_chatItem.size() + items.size() - 1
);
m_chatItem.append(items);
endInsertRows();
}
void addTwoMoreItems()
{
QVector<QString> items;
for (int i = 1; i <= 2; ++i)
items.push_back(QStringLiteral("New item %1").arg(i));
addChatItems(items);
}
private:
QVector<QString> m_chatItem;
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
ChatListItemModel model;
QVector<QString> items;
for (int i = 1; i <= 99; ++i)
items.push_back(QStringLiteral("Item %1").arg(i));
model.addChatItems(items);
QListView view;
view.setModel(&model);
view.show();
view.scrollToBottom();
QTimer::singleShot(5000, &model, &ChatListItemModel::addTwoMoreItems);
return app.exec();
}
推荐阅读
- psycopg2 - psycopg2 在子包 _psycopg 上的 aws 胶水上失败
- python - 如何制作条形图的分箱版本?
- php - Laravel Blade 不显示来自控制器的数据
- c - 如何使用 if 语句选择要显示的不同单词?
- javascript - 如何在多个部分中显示单个数组数据--javascript
- reactjs - 无法测试样式显示的元素:无
- python - 列表数学运算列表
- c++ - 在 C++ 中打印十六进制字符
- typescript - Typescript 命令行选项参考
- performance - 为什么我们需要增加 Google Cloud 中的磁盘大小来提高性能?