C++ 如何响应QT'中的内部移动;QStringListModel的列表视图
我的应用程序快完成了。当我在一个以QStringListModel为后端的简单listview模型中向上或向下移动一个项目时,我一直在尝试更新主窗口的元素 以下是我允许拖放的模型:C++ 如何响应QT'中的内部移动;QStringListModel的列表视图,c++,qt,C++,Qt,我的应用程序快完成了。当我在一个以QStringListModel为后端的简单listview模型中向上或向下移动一个项目时,我一直在尝试更新主窗口的元素 以下是我允许拖放的模型: #ifndef MYMODEL_H #define MYMODEL_H #include <QStringListModel> class mymodel : public QStringListModel { public: mymodel(QObject * parent = nullpt
#ifndef MYMODEL_H
#define MYMODEL_H
#include <QStringListModel>
class mymodel : public QStringListModel
{
public:
mymodel(QObject * parent = nullptr);
Qt::ItemFlags flags(const QModelIndex &index) const;
};
#endif // MYMODEL_H
这是我的实现,它确实可以工作,除非我无法检测是否将行向上向下移动
//create model
model = new mymodel(this);
//make some data
QStringList List;
List << "one" << "two" << "three";
// populate the model
model->setStringList(List);
// create a list view
QListView *lv = new QListView(this);
// glue model and view together
lv->setModel(model);
// allow modifying the data in Listview
lv->setDragDropMode(QAbstractItemView::InternalMove);
lv->setDragDropOverwriteMode(false);
lv->setEditTriggers(QAbstractItemView::AnyKeyPressed |
QAbstractItemView::DoubleClicked);
rowsMoved在标题中声明为:
void rowsMoved(const QModelIndex &parent, int start, int end, const QModelIndex &destination, int row);
};
在此期间,我发现在构造函数中添加:
lv->installEventFilter(this);
在cpp中以及后来定义为:
bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
if (object == lv)
{
if (event->type() == QEvent::ChildRemoved) {
qDebug() << "drop event!";
// iterate over the listview and print out it's data,
// so if you wanted this back in your stringlist.. this is
// where you'd do it:
for (int i = 0; i < model->rowCount(); ++i)
{
qDebug().noquote() << model->index(i, 0).data(Qt::DisplayRole).toString();
}
return true;
}
}
return false;
}
bool主窗口::事件过滤器(QObject*对象,QEvent*事件)
{
if(object==lv)
{
如果(事件->类型()==QEvent::ChildRemoved){
qDebug()行计数();++i)
{
qDebug().noquote()索引(i,0).data(Qt::DisplayRole).toString();
}
返回true;
}
}
返回false;
}
这给了我一个“穷人的通知”,但感觉“肮脏”非常感谢eyllanesc帮助了我!多谢各位 如果有人需要,请在此发布 这段代码确实允许我编辑项目,在列表视图中上下移动项目,并在用户更改列表中的某些内容时收到通知。此外,下面未显示,下面允许拖放 来自文件管理器的操作,这是我需要的应用程序 如果你比较我基于QStringListModel的原始帖子,你会发现它们看起来几乎完全一样。我仍然感到困惑,为什么使用该模型不起作用。但事实就是事实,这一个有效,另一个无效 mymodel.h
#ifndef MYMODEL_H
#define MYMODEL_H
#include <QStandardItemModel>
class mymodel : public QStandardItemModel
{
public:
mymodel(QObject * parent = nullptr);
Qt::ItemFlags flags(const QModelIndex &index) const;
};
#endif // MYMODEL_H
#如果没有我的模型#
#定义MYMODEL_H
#包括
mymodel类:公共QStandardItemModel
{
公众:
mymodel(QObject*parent=nullptr);
Qt::ItemFlags flags(常量QModelIndex&index)常量;
};
#endif//MYMODEL_H
mymodel.cpp
#include "mymodel.h"
#include <QDebug>
mymodel::mymodel(QObject *parent) : QStandardItemModel (parent) {}
Qt::ItemFlags mymodel::flags(const QModelIndex &index) const
{
Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);
if (index.isValid())
{
return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled |
Qt::ItemIsEnabled | Qt::ItemIsEditable;
}
else
{
return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled |
Qt::ItemIsDropEnabled | defaultFlags;
}
}
#包括“mymodel.h”
#包括
mymodel::mymodel(QObject*parent):QStandardItemModel(parent){}
Qt::ItemFlags mymodel::flags(常量QModelIndex&index)常量
{
Qt::ItemFlags defaultFlags=QStandarItemModel::flags(索引);
if(index.isValid())
{
返回Qt::ItemIsSelectable | Qt::ItemIsDragEnabled|
Qt::ItemIsEnabled | Qt::ItemIsEditable;
}
其他的
{
返回Qt::ItemIsSelectable | Qt::ItemIsDragEnabled|
Qt::ItemisProperted | defaultFlags;
}
}
主窗口
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QListView>
#include <QStandardItemModel>
#include <QStringList>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QListView *lv;
QStringList list;
QStandardItemModel *model;
private slots:
void itemChanged();
};
#endif // MAINWINDOW_H
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QListView>
#include <QStandardItemModel>
#include <QStringList>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QListView *lv;
QStringList list;
QStandardItemModel *model;
private slots:
void itemChanged();
};
#endif // MAINWINDOW_H
\ifndef主窗口
#定义主窗口
#包括
#包括
#包括
类主窗口:公共QWidget
{
Q_对象
公众:
主窗口(QWidget*parent=nullptr);
~main窗口();
QListView*lv;
QStringList表;
QStandardItemModel*模型;
专用插槽:
void itemChanged();
};
#endif//main窗口
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QBoxLayout>
#include <QDebug>
#include "mymodel.h"
MainWindow::MainWindow(QWidget *parent)
{
lv = new QListView(this);
model = new mymodel(lv);
list << "one" << "two" << "three";
for (int i=0; i < list.length(); ++i)
{
model->appendRow(new QStandardItem(list[i]));
}
lv->setModel(model);
lv->setDragDropMode(QAbstractItemView::InternalMove);
lv->setDragDropOverwriteMode(false);
QBoxLayout *lo = new QBoxLayout(QBoxLayout::LeftToRight);
lo->addWidget(lv);
setLayout(lo);
connect(model, &QStandardItemModel::itemChanged,
this, &MainWindow::itemChanged);
}
MainWindow::~MainWindow()
{
}
void MainWindow::itemChanged()
{
qDebug().noquote() << "an item changed";
}
#包括“mainwindow.h”
#包括“ui_main window.h”
#包括
#包括
#包括“mymodel.h”
主窗口::主窗口(QWidget*父窗口)
{
lv=新的QListView(本);
模型=新的mymodel(lv);
列表setDragDropMode(QAbstractItemView::InternalMove);
lv->setDragDropOverwriteMode(假);
QBoxLayout*lo=新的QBoxLayout(QBoxLayout::LeftToRight);
lo->addWidget(lv);
设置布局(lo);
连接(模型和QStandarItemModel::itemChanged,
此文件(主窗口::项目已更改)(&MainWindow::itemChanged);
}
MainWindow::~MainWindow()
{
}
void MainWindow::itemChanged()
{
qDebug().noquote()一个问题:为什么要检测位移是从上到下还是从下到下?数据源似乎永远不会更新。在我的例子中,我使用的是字符串列表。因此,当我在列表视图中进行更改时,一些简单的操作,比如上下移动一个项,这些更改永远不会传播到数据集中。因此,我被留在了一个不一致的列表中tate。因此,我正在查找列表视图数据何时更改,或何时移动,并将其写回新列表。QStringListModel是一个不允许修改内部数据的模型,为什么不使用QStandardItemModel?我不确定我的“修改内部数据”是什么意思:我已经在删除行、插入行、从fi中拖动项我只是想找到一种方法来钩住用户修改数据时必须发出的信号。使用eventFilter没有意义,因为QEvent::ChildRemoved事件只有在QObject的QObject子对象被删除并且模型的项不是QObject时才会发送,这样事件就不会被发出。no this也不起作用…当拖动内部项时,它会留下重复项。更新,它起作用,数据更改事件在removeRows之前触发,因此我看到一个ghost/doube,但调试器显示它已被删除。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QBoxLayout>
#include <QDebug>
#include "mymodel.h"
MainWindow::MainWindow(QWidget *parent)
{
lv = new QListView(this);
model = new mymodel(lv);
list << "one" << "two" << "three";
for (int i=0; i < list.length(); ++i)
{
model->appendRow(new QStandardItem(list[i]));
}
lv->setModel(model);
lv->setDragDropMode(QAbstractItemView::InternalMove);
lv->setDragDropOverwriteMode(false);
QBoxLayout *lo = new QBoxLayout(QBoxLayout::LeftToRight);
lo->addWidget(lv);
setLayout(lo);
connect(model, &QStandardItemModel::itemChanged,
this, &MainWindow::itemChanged);
}
MainWindow::~MainWindow()
{
}
void MainWindow::itemChanged()
{
qDebug().noquote() << "an item changed";
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QListView>
#include <QStandardItemModel>
#include <QStringList>
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
QListView *lv;
QStringList list;
QStandardItemModel *model;
private slots:
void itemChanged();
};
#endif // MAINWINDOW_H