Implement QAbstractItemModel.setData() and 5th tutorial example

This commit is contained in:
Simon Edwards 2021-08-15 09:55:15 +02:00
parent 588093519a
commit e81b5ae658
6 changed files with 118 additions and 2 deletions

View File

@ -28,7 +28,8 @@
"example-modelview_1_readonly": "node ./scripts/qode.js dist/examples/modelview_1_readonly.js",
"example-modelview_2_formatting": "node ./scripts/qode.js dist/examples/modelview_2_formatting.js",
"example-modelview_3_changingmodel": "node ./scripts/qode.js dist/examples/modelview_3_changingmodel.js",
"example-modelview_4_headers": "node ./scripts/qode.js dist/examples/modelview_4_headers.js"
"example-modelview_4_headers": "node ./scripts/qode.js dist/examples/modelview_4_headers.js",
"example-modelview_5_edit": "node ./scripts/qode.js dist/examples/modelview_5_edit.js"
},
"engines": {
"node": ">=14.x.x"

View File

@ -102,6 +102,19 @@ class DLL_EXPORT NAbstractItemModel : public QAbstractItemModel, public EventWid
return *variant;
}
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override {
Napi::Env env = this->dispatchOnNode.Env();
Napi::HandleScope scope(env);
auto modelIndexWrap = QModelIndexWrap::constructor.New({Napi::External<QModelIndex>::New(env, new QModelIndex(index))});
auto valueWrap = QVariantWrap::constructor.New({Napi::External<QVariant>::New(env, new QVariant(value))});
auto roleValue = Napi::Value::From(env, role);
Napi::Value booleanJs = this->dispatchOnNode.Call({Napi::String::New(env, "setData"), modelIndexWrap, valueWrap, roleValue});
return booleanJs.As<Napi::Boolean>().Value();
}
QModelIndex _protected_createIndex(int row, int column) const {
return createIndex(row, column);
}

View File

@ -28,4 +28,5 @@ class DLL_EXPORT QAbstractItemModelWrap : public Napi::ObjectWrap<QAbstractItemM
Napi::Value createIndex(const Napi::CallbackInfo& info);
Napi::Value _super_flags(const Napi::CallbackInfo& info);
Napi::Value emitDataChanged(const Napi::CallbackInfo& info);
Napi::Value checkIndex(const Napi::CallbackInfo& info);
};

View File

@ -16,6 +16,7 @@ Napi::Object QAbstractItemModelWrap::init(Napi::Env env, Napi::Object exports) {
InstanceMethod("createIndex", &QAbstractItemModelWrap::createIndex),
InstanceMethod("_super_flags", &QAbstractItemModelWrap::_super_flags),
InstanceMethod("emitDataChanged", &QAbstractItemModelWrap::emitDataChanged),
InstanceMethod("checkIndex", &QAbstractItemModelWrap::checkIndex),
QOBJECT_WRAPPED_METHODS_EXPORT_DEFINE(QAbstractItemModelWrap)});
constructor = Napi::Persistent(func);
exports.Set(CLASSNAME, func);
@ -96,4 +97,15 @@ Napi::Value QAbstractItemModelWrap::emitDataChanged(const Napi::CallbackInfo& in
emit this->instance->dataChanged(*topLeftIndex, *bottomRightIndex, roles);
return env.Null();
}
}
Napi::Value QAbstractItemModelWrap::checkIndex(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
QModelIndexWrap* modelIndexWrap = Napi::ObjectWrap<QModelIndexWrap>::Unwrap(info[0].As<Napi::Object>());
QModelIndex* index = modelIndexWrap->getInternalInstance();
auto result = Napi::Value::From(env, static_cast<uint>(this->instance->checkIndex(*index)));
return result;
}

View File

@ -0,0 +1,72 @@
import { ItemDataRole, ItemFlag, QAbstractTableModel, QModelIndex, QTableView, QVariant } from '..';
function main(): void {
const tableView = new QTableView();
const model = new MyModel();
tableView.setModel(model);
tableView.show();
(global as any).win = tableView;
}
const ROWS = 2;
const COLS = 3;
class MyModel extends QAbstractTableModel {
private _data: string[][] = [];
constructor() {
super();
for (let row = 0; row < ROWS; row++) {
this._data[row] = [];
for (let col = 0; col < COLS; col++) {
this._data[row][col] = '';
}
}
}
rowCount(parent = new QModelIndex()): number {
return ROWS;
}
columnCount(parent = new QModelIndex()): number {
return COLS;
}
data(index: QModelIndex, role = ItemDataRole.DisplayRole): QVariant {
if (role == ItemDataRole.DisplayRole && this.checkIndex(index)) {
return new QVariant(this._data[index.row()][index.column()]);
}
return new QVariant();
}
flags(index: QModelIndex): ItemFlag {
return ItemFlag.ItemIsEditable | super.flags(index);
}
setData(index: QModelIndex, value: QVariant, role: number): boolean {
if (role == ItemDataRole.EditRole) {
if (!this.checkIndex(index)) {
return false;
}
//save value from editor to member m_gridData
this._data[index.row()][index.column()] = value.toString();
//for presentation purposes only: build and emit a joined string
let result = '';
for (let row = 0; row < ROWS; row++) {
for (let col = 0; col < COLS; col++) {
result += this._data[row][col] + ' ';
}
}
console.log(result);
return true;
}
return false;
}
}
main();

View File

@ -80,6 +80,15 @@ export class QAbstractItemModel extends NodeObject<any> {
}
return new QVariant().native;
case 'setData':
try {
return this.setData(new QModelIndex(args[0]), new QVariant(args[1]), args[2]);
} catch (e) {
console.log(`An exception was thrown while dispatching to method 'setData':`);
console.log(e);
}
return false;
default:
return null;
}
@ -116,6 +125,10 @@ export class QAbstractItemModel extends NodeObject<any> {
return new QModelIndex(result);
}
checkIndex(index: QModelIndex): boolean {
return this.native.checkIndex(index.native);
}
flags(index: QModelIndex): ItemFlag {
return this.native._super_flags(index.native);
}
@ -127,4 +140,8 @@ export class QAbstractItemModel extends NodeObject<any> {
headerData(section: number, orientation: Orientation, role: number): QVariant {
return new QVariant();
}
setData(index: QModelIndex, value: QVariant, role = ItemDataRole.EditRole): boolean {
return false;
}
}