【发布时间】:2018-11-20 16:23:22
【问题描述】:
我创建了一个从 QListView 扩展的可扩展 ListView,当我只想显示标题数据(未扩展的项目)时一切正常,因为我给它一个硬编码的高度,即 64,出现细节展开项目时。但问题是我不知道细节的确切高度,因为细节可以一行或多行,我想根据项目内容适合项目高度。
这里是当项目展开或折叠时处理点击监听的代码:
LogListItemDelegate *delegate = static_cast<LogListItemDelegate *>(itemDelegate());
QStandardItem *item = static_cast<QStandardItemModel *>(model())->itemFromIndex(index);
bool expand = delegate->isExpandable() && mapFromGlobal(QCursor::pos()).x() >= visualRect(index).width() - 48;
bool expanded = index.data(LogListItemDelegate::DT_Expanded).toBool();
// here the height returned is header height, no containing the details which it is in expanding mode
int height = item->sizeHint().height();
if (!expanded) {
item->setData(true, LogListItemDelegate::DT_Expanded);
item->setSizeHint(QSize(0, 150)); // 150 here must be dynamically calculated
} else {
item->setData(false, LogListItemDelegate::DT_Expanded);
item->setSizeHint(QSize(0, 64)); // 64 is the header height, no prolem
}
现在的问题是:item展开时如何计算高度?
结果:
编辑:
It is when I want to add the message to the list
void LogListView::addMessage(const QJsonObject &msg, const bool append)
{
static int id = 1; // unique id for log items
auto *item = new QStandardItem();
item->setEditable(false);
item->setData(QString("%1").arg(id++, 5, 10, QChar('0')), LogListItemDelegate::DT_Id);
item->setData(msg["icon"], LogListItemDelegate::DT_ICON);
item->setData(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"), LogListItemDelegate::DT_Timestamp);
item->setData(msg["title"], LogListItemDelegate::DT_Title);
item->setData(msg["subtitle"], LogListItemDelegate::DT_Subtitle);
item->setData(msg["details"], LogListItemDelegate::DT_Details);
item->setData(false, LogListItemDelegate::DT_Expanded);
// here I am unable to calculate the height, because the details does not have a specific height to set here,
// so when append the item to the list it is unvisible. If set the height 64, it is the exact height of the item without details, which is good
//item->setSizeHint(QSize(0, 64));
static_cast<QStandardItemModel *>(model())->appendRow(item);
scrollToBottom();
}
就是sizeHint()中的代码
QSize LogListItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
bool expanded = index.data(DT_Expanded).toBool();
QFont fntDetials = option.font;
fntDetials.setPointSize(12);
QRect r = option.rect;
QFontMetrics fm(fntDetials);
QString details = index.data(DT_Details).toString();
QRect br = fm.boundingRect(r, Qt::TextWordWrap, details);
return QSize(option.rect.width(), br.height()+64);
}
可惜不行……,我觉得Qt可以看看Android ListView及其回收功能来解决ListView的问题,这样一来,我觉得是非常非常痛苦的。
【问题讨论】:
-
QStandardItem 不是视觉元素,而是保存数据的元素。几何任务取决于具有 sizeHint 方法的委托,因此问题出在委托中。为了给你一个解决方案,它显示了委托的代码
-
@eyllanesc 首先感谢您的回复!我在 Delegate 中没有找到任何将正确的高度和宽度传递给 ListView 的东西。你能告诉我如何将细节的高度传递给 ListView,我可以计算细节的高度,但是没有办法设置高度以在单击项目时将其取回?
-
@BahramdunAdil,我以为你不喜欢这个解决方案。 The answer 未被接受,但您正在使用我的代码。这似乎不是一场公平的比赛。 我创建了一个可扩展的 ListView 听起来很神圣。
-
@scopchanov 问题仍然没有解决,所以当功能完全实现时,我会回来,谢谢并接受真正解决问题的答案。顺便说一句,您的答案已获得投票。而且您的解决方案也不是可扩展的项目视图。而且我连一行都没有使用你的代码。因为你的解决方案不是我想要的。谢谢!!
-
@BahramdunAdil,哪个问题仍未解决?您提出了一个问题并通过工作示例得到了答案。然后你抱怨它对你来说太复杂了。不过,您使用了我的解决方案,甚至没有提及(在您当前的问题中)您从哪里得到它。有了这样的态度,你不会得到太多帮助。但最好的部分是,我知道如何使展开项的高度适合文本,因为我已经编写了代码,而你没有。
标签: c++ qt qt5 qlistview qstandarditem