QML:GridView 在 C++ 中更改其模型后不更新
我的出发点是以下 QML 源代码,其中 GridView 显示 ListModel 并带有漂亮的项目交换动画:
My starting point is the following QML source, where GridView is showing ListModel with nice animation of item swaps:
import QtQuick 1.1
GridView {
id: mainGrid
width: 825; height: 400; cellWidth: 165; cellHeight: 95
model: myModel
delegate: myButton
ListModel {
id: myModel
function createModel() {
for (var i=1; i<=20; i++) {
append({"display":i})
}
}
function listItems() {
console.log("LIST OF ITEMS")
for (var i=0; i<=19; i++) {
console.log("model["+i+"]="+get(i).display)
}
}
function moveItem(inx1,inx2) {
move(inx1,inx2,1)
}
Component.onCompleted: {
createModel()
listItems()
}
}
Component {
id: myButton
Item {
id: item
width: 160; height: 90
Rectangle {
id: box
parent: mainGrid
x: item.x; y: item.y; width: item.width; height: item.height; border.width: 1
Behavior on x {NumberAnimation { duration: 1000;} }
Behavior on y {NumberAnimation { duration: 1000;} }
Text {
anchors.centerIn: parent
text: display
}
MouseArea {
anchors.fill: parent
onClicked: {
mainGrid.model.moveItem(index,0)
mainGrid.model.listItems()
}
}
}
}
}
}
我想使用从 QStandardItemModel 派生的 C++ 模型,而不是 QML ListModel:
Instead of QML ListModel I want to use a C++ model which is derived from QStandardItemModel:
#include <QStandardItemModel>
class MyTable : public QStandardItemModel
{
private:
Q_OBJECT
int table[20];
public:
explicit MyTable(QObject *parent = 0) : QStandardItemModel(parent) {}
Q_INVOKABLE void createModel();
Q_INVOKABLE void moveItem(int inx1, int inx2);
};
这个模型通过 qmlRegisterType<MyTable,1>("MyTable",1,0,"MyTable")
暴露给 QML.问题是,我没有得到很好的动画效果,我也不确定交换后模型是否正确更新.
This model is exposed to QML via qmlRegisterType<MyTable,1>("MyTable",1,0,"MyTable")
.
The problem is, that I do not get the nice animation effect and I am also not sure if after the swap the model is correctly updated.
相关的(有问题的)C++ 函数在这里:
The related (problematic) C++ functions are here:
void MyTable::createModel()
{
for (unsigned int i=0; i<20; i++) {
table[i]=i;
QStandardItem* item = new QStandardItem(QString("%1").arg(table[i]));
appendRow(item);
}
}
void MyTable::moveItem(int inx1, int inx2) {
//SOME MATH, IT WORKS
int tmp = table[inx1];
if (inx1<inx2) {
for (int i=inx1; i<inx2; i++) table[i] = table[i+1];
table[inx2] = tmp;
} else if (inx2<inx1) {
for (int i=inx1; i>inx2; i--) table[i] = table[i-1];
table[inx2] = tmp;
}
//UPDATE MODEL - IS SOMETHING MISSING HERE?
for (unsigned int i=0; i<20; i++) {
QStandardItem* item = new QStandardItem(QString("%1").arg(table[i]));
setItem(i,0,item);
}
}
推荐答案
我找到了解决方案.这是工作代码(感谢 Borut123 的建议).
I found the solution. Here is the working code (thanks Borut123 for suggestions).
class MyTable : public QStandardItemModel
{
private:
Q_OBJECT
public:
explicit MyTable(QObject *parent = 0) : QStandardItemModel(parent) {}
Q_INVOKABLE void createModel();
Q_INVOKABLE void moveItem(int inx1, int inx2);
Q_INVOKABLE void listItems();
};
void MyTable::createModel()
{
for (unsigned int i=0; i<20; i++) {
QStandardItem* item = new QStandardItem(QString("%1").arg(i));
appendRow(item);
}
}
void MyTable::moveItem(int inx1, int inx2) {
bool ok = false;
if (inx1 < inx2) ok = beginMoveRows(QModelIndex(),inx1,inx1,QModelIndex(),inx2+1);
if (inx1 > inx2) ok = beginMoveRows(QModelIndex(),inx1,inx1,QModelIndex(),inx2);
if (!ok) return;
QStandardItem* tmp1 = takeItem(inx1);
if (inx1<inx2) {
for (int i=inx1; i<inx2; i++) {
QStandardItem* tmp2 = takeItem(i+1);
setItem(i,tmp2);
}
} else if (inx2<inx1) {
for (int i=inx1; i>inx2; i--) {
QStandardItem* tmp2 = takeItem(i-1);
setItem(i,tmp2);
}
}
setItem(inx2,tmp1);
endMoveRows();
}
void MyTable::listItems() {
qDebug() << "LIST OF ITEMS";
for (unsigned int i=0; i<20; i++) {
qDebug() << QString("table[%1]=%2").arg(i).arg(item(i)->text()).toAscii().data();
}
}
相关文章