具有最简单委托的ListView如果试图设置其委托anchors属性并滚动列表(这会使委托被销毁/创建),就会产生大量警告"21:35:31.911 warning T#16084047 unknown - qrc:/main.qml:15: TypeError: Cannot read property 'left' of null"。Qt 5.12或5.9的情况并非如此。
文件main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
ListView {
anchors.fill: parent
model: cppModel
delegate: Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: 50
Text { text: model.itemName }
}
}
}文件main.cpp
#include <QAbstractListModel>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QtGlobal>
#include <QQmlContext>
#include <iostream>
void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
QString logLine = qFormatLogMessage(type, context, msg);
std::cout << logLine.toStdString() << std::endl;
}
class CppModel: public QAbstractListModel {
// QAbstractItemModel interface
public:
virtual int rowCount(const QModelIndex &parent) const override { return 100; }
virtual QVariant data(const QModelIndex &index, int role) const override {
if (role == (Qt::DisplayRole + 1)) {
return QString("Element %1").arg(index.row());
}
return QVariant();
}
virtual QHash<int, QByteArray> roleNames() const override {
return {{(Qt::DisplayRole+1), "itemName"}};
}
};
int main(int argc, char *argv[])
{
qSetMessagePattern("%{time hh:mm:ss.zzz} %{type} T#%{threadid} %{function} - %{message}");
qInstallMessageHandler(myMessageHandler);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
CppModel cppModel;
engine.rootContext()->setContextProperty("cppModel", &cppModel);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}我做错了什么,以及如何正确设置委托元素的anchors?
发布于 2020-09-07 11:35:17
这是Qt 5.15中行为改变的结果。第一个问题是关于这里的报道,并附有更详细的这里摘要。新文件说:
委托将根据需要实例化,并可随时销毁。因此,状态不应存储在委托中。委托通常是ListView的contentItem的父代理,但通常取决于它在视图中是否可见,父代理可以更改,有时为null。因此,不建议从委托内绑定到父属性。如果希望委托填写ListView的宽度,请考虑使用以下方法之一: ListView { id: listView // .代表:项目{ //不正确。宽度: parent.width //更正。宽度: listView.width宽度: ListView.view.width //…}
所以,你可以:
ListView一个id,并在绑定中使用它,而不是parent。ListView.view)访问视图。anchors.left: parent ? parent.left : undefined)。选项1和2将产生更干净的代码。
选项1导致创建一个较少的QObject (每个附加的对象都是一个QObject),但将委托绑定到该特定视图。
选项2更适合于将与其他ListView一起重用的独立组件的委托。
https://stackoverflow.com/questions/63767669
复制相似问题