我有从QAbstractTableModel继承的C ++类,下一个函数覆盖:
virtual QHash<int, QByteArray> roleNames() const noexcept override;
virtual Qt::ItemFlags flags(const QModelIndex& index) const noexcept override;
virtual int rowCount(const QModelIndex& parent = QModelIndex()) const noexcept override;
virtual int columnCount(const QModelIndex& parent = QModelIndex()) const noexcept override;
virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const noexcept override;
virtual bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()) noexcept override;
virtual bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()) noexcept override;
virtual bool setData(const QModelIndex& index, const QVariant& data, int role = Qt::EditRole) noexcept override;
模型有3列,第一列是readonly,last是可编辑的,所以这是flags()方法实现:
Qt::ItemFlags ObjectInitialStateModel::flags(const QModelIndex& index) const noexcept
{
if (index.column() == 0)
{
return Qt::ItemIsEnabled | Qt::ItemNeverHasChildren;
}
else
{
return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemNeverHasChildren;
}
}
在QML中,零件模型显示正常,但我不知道如何在TableView中编辑2列和3列的模型数据。我曾尝试写过列委托:
Item {
id: item
state: "labelMode"
Text {
id: textLabel
text: styleData.value
anchors.fill: parent
renderType: Text.NativeRendering
}
TextField {
id: textField
text: styleData.value
anchors.fill: parent
Keys.onEnterPressed: commit()
Keys.onReturnPressed: commit()
Keys.onEscapePressed: rollback()
function commit() {
item.state = "labelMode"
}
function rollback() {
item.state = "labelMode"
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
onDoubleClicked: item.state = "editMode"
}
states: [
State {
name: "labelMode"
PropertyChanges {
target: textLabel
visible: true
}
PropertyChanges {
target: mouseArea
visible: true
}
PropertyChanges {
target: textField
visible: false
}
},
State {
name: "editMode"
PropertyChanges {
target: textLabel
visible: false
}
PropertyChanges {
target: mouseArea
visible: false
}
PropertyChanges {
target: textField
visible: true
focus: true
}
}
]
}
但我不知道如何正确地在commit()函数中为模型设置新数据。 或者可能有另一种在QML中使用可编辑列和C ++模型实现表的正确方法?
答案 0 :(得分:2)
我找到了一个解决方案:
property var cppModel
TableViewColumn {
role: "u"
title: qsTr("u(t)")
width: initialStateTableView.width / 3
delegate: EditableDelegate {
cppModel: DataSetService.currentDataSet ? DataSetService.currentDataSet.initialStateModel : null
}
}
Q_INVOKABLE bool setData(int row, int column, const QVariant& data) noexcept;
调用默认的setData方法
function commit() {
cppModel.setData(styleData.row, styleData.column, text)
item.state = "labelMode"
}
但我认为这是丑陋的大黑客,如果有人知道更优雅的解决方案,请分享一下......
答案 1 :(得分:1)
除了roleNames()
和data()
之外,可编辑模型还必须重新实现setData()
函数以保存对现有数据的更改。在执行实际更新之前,以下版本的方法检查给定的模型索引是否有效且角色是否等于Qt::EditRole
。根据模型,您还可以/必须调用函数的父类版本:
bool EditableModel::setData(const QModelIndex &item, const QVariant &value, int role)
{
if (item.isValid() && role == Qt::EditRole) {
// update logic
emit dataChanged(item, item);
return true;
}
return false;
}
应该注意的是,与C ++项目视图(例如QListView
或QTableView
不同,必须在适当时从QML显式调用setData()
方法。