Сразу прошу прощение за название, не отражающее сущности вопроса (другого не придумал))) и за размеры вопроса (с лаконичностью у меня так же плохо, как и с фантазией).
Итак, проблема следующая:
Нужно было наладить drag and drop между двумя списками. Для этого я написал класс, унаследованный от QListWidget (своего, собственно, ничего не придумал, а подсмотрел в книжке Жасмин Бланшет "Qt4: Программирование GUI на C++"):
C++ (Qt)
List.h
#ifndef LIST_H
#define LIST_H
#include <QListWidget>
class List : public QListWidget
{
Q_OBJECT
public:
List(QWidget *prnt = 0);
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
private:
void startDrag();
QPoint startPos;
};
#endif //LIST_H
C++ (Qt)
List.cpp
#include "List.h"
#include <QtGui/QApplication>
#include <QMouseEvent>
//--------------------------------------------------------------------------------------
List::List(QWidget *prnt /* = 0 */): QListWidget(prnt)
{
setSelectionMode(QAbstractItemView::SingleSelection);
setDragEnabled(true);
viewport()->setAcceptDrops(true);
setDropIndicatorShown(true);
}
//--------------------------------------------------------------------------------------
//---------------------------------Events-----------------------------------------------
//--------------------------------------------------------------------------------------
void List::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton)
startPos=event->pos();
QListWidget::mousePressEvent(event);
}
//--------------------------------------------------------------------------------------
void List::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton)
{
int distance = (event->pos() - startPos).manhattanLength();
if(distance >= QApplication::startDragDistance())
startDrag();
}
QListWidget::mouseMoveEvent(event);
}
//--------------------------------------------------------------------------------------
void List::dragEnterEvent(QDragEnterEvent *event)
{
List* source = qobject_cast<List *>(event->source());
if(source && source != this)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
}
//--------------------------------------------------------------------------------------
void List::dragMoveEvent(QDragMoveEvent *event)
{
List* source = qobject_cast<List *>(event->source());
if(source && source != this)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
}
//--------------------------------------------------------------------------------------
void List::dropEvent(QDropEvent *event)
{
List* source = qobject_cast<List *>(event->source());
if(source && source != this)
{
addItem(event->mimeData()->text());
event->setDropAction(Qt::MoveAction);
event->accept();
}
}
//--------------------------------------------------------------------------------------
//----------------------------------Functions-------------------------------------------
//--------------------------------------------------------------------------------------
void List::startDrag()
{
QListWidgetItem* _item = currentItem();
if(_item)
{
QMimeData* mimeData = new QMimeData;
mimeData->setText(_item->text());
QDrag* drag = new QDrag(this);
drag->setMimeData(mimeData);
if(drag->exec(Qt::MoveAction) == Qt::MoveAction)
delete _item;
}
}
Все нормально работает, но меня смущает следующее место:
C++ (Qt)
void List::startDrag()
{
QListWidgetItem* _item = currentItem();
if(_item)
{
QMimeData* mimeData = new QMimeData;
mimeData->setText(_item->text());
QDrag* drag = new QDrag(this);
drag->setMimeData(mimeData);
if(drag->exec(Qt::MoveAction) == Qt::MoveAction)
delete _item;
}
}
mimeData и drag создаются, но нигде не удаляются. Не будет ли утечки памяти? Или я ошибаюсь, и они все-таки где-то удаляются?
З.Ы.: Попытка сделать их auto_ptr не удалась:
C++ (Qt)
//List.h
.....
std::auto_ptr<QMimeData> mimeData;
std::auto_ptr<QDrag> drag;
.....
//List.cpp
......
void List::startDrag()
{
QListWidgetItem* _item = currentItem();
if(_item)
{
mimeData.reset(new QMimeData);
mimeData->setText(_item->text());
drag.reset(new QDrag(this));
drag->setMimeData(mimeData.get());
if(drag->exec(Qt::MoveAction) == Qt::MoveAction)
delete _item;
}
}
Данная функция нормально срабатывает один раз, но на второй - падает на mimeData.reset(new QMimeData). Буду благодарен, если кто-нибудь объяснит, почему это происходит.