Qt Qml Error: Unable to assign [undefined] to QString in a subclassed QAbstractItemModel for Qml TreeView
Qt Qml Error: Unable to assign [undefined] to QString in a subclassed QAbstractItemModel for Qml TreeView
我尝试为 Qml TreeView 创建一个自定义模块,我使用 Simpel Treeview Example 作为基础,但我总是得到 "unabe to assign [undefined] to QString".
这里有一些你可能需要的信息:
Displayed view
Qml:
import QtQuick 2.0
import QtQuick.Controls 1.4
import cci.screenshotCreator.StructureDataModel 1.0
TreeView {
id: root
state: "closed"
TableViewColumn {
role: "folderName"
title: "Ordnerstruktur"
}
model: StructureDataModel{
id: dataModel
}
itemDelegate: Item {
height: 30
Rectangle {
id: rectangle
color: styleData.selected ? "lightgray" : "#ffffff"
border.width: styleData.selected ? 2 : 1
border.color: styleData.selected ? "lightblue" : "#ababab"
anchors.fill: parent
}
Text {
id: folderText
text: dataModel.folderName
fontSizeMode: Text.Fit
anchors.fill: parent
font.pointSize: 12
verticalAlignment: Text.AlignLeft
}
C++:
#include "structuredatamodel.h"
structureDataModel::structureDataModel(QObject *parent)
: QAbstractItemModel(parent)
{
QList<QVariant> rootData;
rootData << "/";
rootItem = new StructureItem(rootData);
setupModelData(rootItem);
}
structureDataModel::~structureDataModel()
{
delete rootItem;
}
QModelIndex structureDataModel::index(int row, int column, const QModelIndex &parent) const
{
if(!hasIndex(row, column, parent))
return QModelIndex();
StructureItem *parentItem;
if(!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<StructureItem*>(parent.internalPointer());
StructureItem *childItem = parentItem->child(row);
if(childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QHash<int, QByteArray> structureDataModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[structureRoles::folderName] = "folderName";
return roles;
}
QModelIndex structureDataModel::parent(const QModelIndex &index) const
{
if(!index.isValid())
return QModelIndex();
StructureItem *childItem = static_cast<StructureItem*>(index.internalPointer());
StructureItem *parentItem = childItem->parentItem();
if (parentItem == rootItem)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int structureDataModel::rowCount(const QModelIndex &parent) const
{
StructureItem *parentItem;
if(parent.column() > 0)
return 0;
if(!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<StructureItem*>(parent.internalPointer());
return parentItem->childCount();
}
int structureDataModel::columnCount(const QModelIndex &parent) const
{
if(parent.isValid())
return static_cast<StructureItem*>(parent.internalPointer())->columnCount();
else
return rootItem->columnCount();
}
QVariant structureDataModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid())
return QVariant();
if(role != structureRoles::folderName)
return QVariant();
StructureItem *item = static_cast<StructureItem*>(index.internalPointer());
return item->data(index.column()).toString();
}
Qt::ItemFlags structureDataModel::flags(const QModelIndex &index) const
{
if(!index.isValid())
return 0;
return QAbstractItemModel::flags(index);
}
QVariant structureDataModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == structureRoles::folderName)
return rootItem->data(section);
return QVariant();
}
void structureDataModel::setupModelData(StructureItem *parent)
{
QList<QVariant> data;
data << "Test";
StructureItem *child = new StructureItem(data, parent);
parent->appendChild(child);
}
StructureItem 与 TreeItem 相同(只是名称不同 :))
我制作了自己的 setupModelData,以便模型只有一行作为根点。
后来我想要一个可编辑的树视图,但现在一个工作的只读树视图现在应该可以工作了。
我怀疑它与 setupModelData 或使 c++ 对 qml 可见有关。
PS:我添加了 qmlRegisterType("cci.screenshotCreator.StructureDataModel", 1, 0, "StructureDataModel");到主文件注册 cpp class.
用于测试的最小应用程序:
https://pastebin.com/u/Klidrack(我的 pastebin 配置文件的所有文件):)
哦,第一眼没看出来。
ListView
和 TreeView
在 QML
中的委托组件之间存在差异。
在 TreeView
中,您有 itemDelegate
并且所有数据都通过 styleData
属性展开。
在你的情况下,这应该是这样的:
itemDelegate: Item
{
height: 30
Rectangle
{
id: rectangle
color: styleData.selected ? "lightgray" : "#ffffff"
border.width: styleData.selected ? 2 : 1
border.color: styleData.selected ? "lightblue" : "#ababab"
anchors.fill: parent
}
Text
{
id: folderText
text: styleData.value
fontSizeMode: Text.Fit
anchors.fill: parent
font.pointSize: 12
verticalAlignment: Text.AlignLeft
}
}
我尝试为 Qml TreeView 创建一个自定义模块,我使用 Simpel Treeview Example 作为基础,但我总是得到 "unabe to assign [undefined] to QString".
这里有一些你可能需要的信息:
Displayed view
Qml:
import QtQuick 2.0
import QtQuick.Controls 1.4
import cci.screenshotCreator.StructureDataModel 1.0
TreeView {
id: root
state: "closed"
TableViewColumn {
role: "folderName"
title: "Ordnerstruktur"
}
model: StructureDataModel{
id: dataModel
}
itemDelegate: Item {
height: 30
Rectangle {
id: rectangle
color: styleData.selected ? "lightgray" : "#ffffff"
border.width: styleData.selected ? 2 : 1
border.color: styleData.selected ? "lightblue" : "#ababab"
anchors.fill: parent
}
Text {
id: folderText
text: dataModel.folderName
fontSizeMode: Text.Fit
anchors.fill: parent
font.pointSize: 12
verticalAlignment: Text.AlignLeft
}
C++:
#include "structuredatamodel.h"
structureDataModel::structureDataModel(QObject *parent)
: QAbstractItemModel(parent)
{
QList<QVariant> rootData;
rootData << "/";
rootItem = new StructureItem(rootData);
setupModelData(rootItem);
}
structureDataModel::~structureDataModel()
{
delete rootItem;
}
QModelIndex structureDataModel::index(int row, int column, const QModelIndex &parent) const
{
if(!hasIndex(row, column, parent))
return QModelIndex();
StructureItem *parentItem;
if(!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<StructureItem*>(parent.internalPointer());
StructureItem *childItem = parentItem->child(row);
if(childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QHash<int, QByteArray> structureDataModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[structureRoles::folderName] = "folderName";
return roles;
}
QModelIndex structureDataModel::parent(const QModelIndex &index) const
{
if(!index.isValid())
return QModelIndex();
StructureItem *childItem = static_cast<StructureItem*>(index.internalPointer());
StructureItem *parentItem = childItem->parentItem();
if (parentItem == rootItem)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int structureDataModel::rowCount(const QModelIndex &parent) const
{
StructureItem *parentItem;
if(parent.column() > 0)
return 0;
if(!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<StructureItem*>(parent.internalPointer());
return parentItem->childCount();
}
int structureDataModel::columnCount(const QModelIndex &parent) const
{
if(parent.isValid())
return static_cast<StructureItem*>(parent.internalPointer())->columnCount();
else
return rootItem->columnCount();
}
QVariant structureDataModel::data(const QModelIndex &index, int role) const
{
if(!index.isValid())
return QVariant();
if(role != structureRoles::folderName)
return QVariant();
StructureItem *item = static_cast<StructureItem*>(index.internalPointer());
return item->data(index.column()).toString();
}
Qt::ItemFlags structureDataModel::flags(const QModelIndex &index) const
{
if(!index.isValid())
return 0;
return QAbstractItemModel::flags(index);
}
QVariant structureDataModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == structureRoles::folderName)
return rootItem->data(section);
return QVariant();
}
void structureDataModel::setupModelData(StructureItem *parent)
{
QList<QVariant> data;
data << "Test";
StructureItem *child = new StructureItem(data, parent);
parent->appendChild(child);
}
StructureItem 与 TreeItem 相同(只是名称不同 :)) 我制作了自己的 setupModelData,以便模型只有一行作为根点。 后来我想要一个可编辑的树视图,但现在一个工作的只读树视图现在应该可以工作了。 我怀疑它与 setupModelData 或使 c++ 对 qml 可见有关。
PS:我添加了 qmlRegisterType("cci.screenshotCreator.StructureDataModel", 1, 0, "StructureDataModel");到主文件注册 cpp class.
用于测试的最小应用程序: https://pastebin.com/u/Klidrack(我的 pastebin 配置文件的所有文件):)
哦,第一眼没看出来。
ListView
和 TreeView
在 QML
中的委托组件之间存在差异。
在 TreeView
中,您有 itemDelegate
并且所有数据都通过 styleData
属性展开。
在你的情况下,这应该是这样的:
itemDelegate: Item
{
height: 30
Rectangle
{
id: rectangle
color: styleData.selected ? "lightgray" : "#ffffff"
border.width: styleData.selected ? 2 : 1
border.color: styleData.selected ? "lightblue" : "#ababab"
anchors.fill: parent
}
Text
{
id: folderText
text: styleData.value
fontSizeMode: Text.Fit
anchors.fill: parent
font.pointSize: 12
verticalAlignment: Text.AlignLeft
}
}