Зачем нужно отсечение в повторителе внутри ListView?
Я столкнулся с этой проблемой, где строки ListView
не всегда правильно выстраиваются Похоже, что это может быть ошибка, но у меня есть обходной путь, где обрезка исправляет это. Но это просто случайность?
Проблема связана с наличием большого количества строк в модели, но все мои строки имеют целочисленную высоту и одинаковы, так что это не должно быть проблемой.
main.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.2
ApplicationWindow
{
visible: true
width: 640
height: 800
property int rowHeaderHeight: 24
// make a list of rows each with the model row height + header height
ListView
{
id: boxview
anchors.fill: parent
// calculate content height (line can be omitted without problem)
contentHeight: (myModel.rowHeight()+rowHeaderHeight)*myModel.rowCount()
model: myModel
delegate: Thing1 { name: model.name; headerHeight: rowHeaderHeight }
Component.onCompleted:
{
// go right to the middle
boxview.positionViewAtIndex(500000, ListView.Beginning);
}
}
}
Thing.qml
import QtQuick 2.5
import QtQuick.Controls 1.4
Item
{
// thing is just a box with a header label
width: parent.width
height: myModel.rowHeight() + headerHeight
property string name
property int headerHeight
// label is the header height
Label
{
width: parent.width
height: headerHeight
verticalAlignment: Text.AlignBottom
text: name
x: 8
}
// then the box
Repeater
{
// but wait! there are 10 of them in the same place
// yes, it works for 1, but goes wrong the more there are
// 10 makes it look obviousl
model: 10
delegate: Rectangle
{
//clip: true // uncomment this to fix the problem, but why?
y: headerHeight
width: parent.width;
height: myModel.rowHeight()
color: "blue"
}
}
}
mymodel.h
#include <QAbstractListModel>
#include <QQmlApplicationEngine>
#include <QObject>
#include <QString>
#include <QDebug>
class MyModel : public QAbstractListModel
{
Q_OBJECT
public:
int _rowCount;
int _rowHeight;
MyModel()
{
_rowCount = 1000000;
_rowHeight = 100;
}
int rowCount(const QModelIndex& parent = QModelIndex()) const override
{
return _rowCount;
}
QVariant data(const QModelIndex &index, int role) const override
{
int ix = index.row();
char buf[128];
sprintf(buf, "Box %d", ix);
return buf;
}
QHash<int, QByteArray> roleNames() const override
{
QHash<int, QByteArray> roles;
roles[Qt::UserRole+1] = "name";
return roles;
}
Q_INVOKABLE int rowHeight()
{
return _rowHeight;
}
};
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <qqmlcontext.h>
#include <qqmlengine.h>
#include <qqmlcontext.h>
#include <qqml.h>
#include <QtQuick/qquickitem.h>
#include <QtQuick/qquickview.h>
#include "mymodel.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
MyModel model;
QQmlContext* ctxt = engine.rootContext();
ctxt->setContextProperty("myModel", &model);
engine.addImportPath(":/.");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
вот что вы видите, когда немного прокручиваете. обратите внимание, что заголовки перекрываются синими полями.
Почему это?
Если repeater
меняется на просто 1
скорее, чем 10
это уходит, но я думаю, что это просто делает его менее вероятным.
если clip:true
строка прокомментирована, это работает, но я не знаю почему.
вот суть файлов проекта. https://gist.github.com/anonymous/8c314426fe4f8764e22819f63e7f50fc
qt5.6 / окна / MinGW
спасибо за любую информацию.
1 ответ
Похоже на QTBUG-43193. От быстрого взгляда, ListView
умножает индекс видимых элементов на высоту делегата, поэтому, возможно, есть некоторые проблемы с точностью при большом количестве моделей.