我们经常会碰到这样的一个问题,我们想把其他地方选中的文本,直接通过拖拽移动到一个控件中,从而实现方便添加项的功能.
这里我们以QListWidget作为例子,来实现这么一个功能:其他地方的文本可直接拖拽进QListWidget中,且QListWidget部件中的文本可相互拖拽,也就是可以从QListWidget中拖拽项到另外一个QListWidget中,实现拖拽项的功能.
首先我们对QListWidget进行子类化的操作,也就是定义一个继承QListWidget的类.
//"QMyListWidget.h"
#ifndef QMYLISTWIDGET_H
#define QMYLISTWIDGET_H
#include <QtGui>
#include <QListWidget>
#include <QApplication>
class QMyListWidget : public QListWidget
{
Q_OBJECT
public:
QMyListWidget(QWidget *parent);
~QMyListWidget();
protected:
//重写下面两个函数来完成从该部件中拖拽出去的操作.
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
//重写下面三个函数来完成接受外来拖拽的操作.
void dragEnterEvent(QDragEnterEvent *event);
void dragMoveEvent(QDragMoveEvent *event);
void dropEvent(QDropEvent *event);
private:
//记录拖拽的起点.
QPoint m_dragPoint;
//记录被拖拽的项.
QListWidgetItem *m_dragItem;
};
#endif // QMYLISTWIDGET_H
接下来我们只要重写这五个函数即可.
//"QMyListWidget.cpp"
#include "QMyListWidget.h"
QMyListWidget::QMyListWidget(QWidget *parent)
: QListWidget(parent)
{
//设置QListWidget接受拖拽.
this->setAcceptDrops(true);
}
QMyListWidget::~QMyListWidget()
{
}
//重写鼠标点击操作.
void QMyListWidget::mousePressEvent(QMouseEvent *event)
{
//确保左键拖拽.
if (event->button() == Qt::LeftButton)
{
//先保存拖拽的起点.
m_dragPoint = event->pos();
//保留被拖拽的项.
m_dragItem = this->itemAt(event->pos());
}
//保留原QListWidget部件的鼠标点击操作.
QListWidget::mousePressEvent(event);
}
void QMyListWidget::mouseMoveEvent(QMouseEvent *event)
{
//确保按住左键移动.
if (event->buttons() & Qt::LeftButton)
{
QPoint temp = event->pos() - m_dragPoint;
//只有这个长度大于默认的距离,才会被系统认为是形成拖拽的操作.
if (temp.manhattanLength() > QApplication::startDragDistance())
{
QDrag *drag = new QDrag(this);
QMimeData *mimeData = new QMimeData;
mimeData->setText(m_dragItem->text());
drag->setMimeData(mimeData);
auto action = drag->exec(Qt::CopyAction | Qt::MoveAction);
if (action == (Qt::CopyAction) || (action == Qt::MoveAction))
{
//当成功拖拽后,删除拖拽项.
auto i = this->takeItem(this->row(m_dragItem));
delete i;
}
}
}
QListWidget::mouseMoveEvent(event);
}
void QMyListWidget::dragEnterEvent(QDragEnterEvent *event)
{
//设置动作为移动动作.
event->setDropAction(Qt::MoveAction);
//然后接受事件.这个一定要写.
event->accept();
}
void QMyListWidget::dragMoveEvent(QDragMoveEvent *event)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
//当拖拽项被放下时的操作.
void QMyListWidget::dropEvent(QDropEvent *event)
{
QString str = event->mimeData()->text();
if (!str.isEmpty())
{
//找到当前鼠标位置在部件中的项.
auto item = this->itemAt(event->pos());
//
if (!item)
this->addItem(str);
else
this->insertItem(this->row(item),str);
event->setDropAction(Qt::MoveAction);
event->accept();
}
}
这样我们就实现了自定义的QListWidget,接下来我们在Qt设计师中,拖拽出两个QListWidget部件.
我们右键点击QListWidget,点击第二个提升为,因为我之前已经提升过了,然后在取消提升,所以就有了提升的记录选项,你们是没有的.
然后输入自定义的类.点击添加,然后点击提升就好了,两个QListWidget都要提升喔.
下面是”c.cpp”下的代码:
#include "c.h"
c::c(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
ui.listWidget->addItems(QStringList()<<"zz"<<"xx"<<"cc");
}
c::~c()
{
}
c.h和main.cpp的代码:
#ifndef C_H
#define C_H
#include <QtWidgets/QWidget>
#include "ui_c.h"
class c : public QWidget
{
Q_OBJECT
public:
c(QWidget *parent = 0);
~c();
private:
Ui::cClass ui;
};
#endif // C_H
//main.cpp
#include "c.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
c w;
w.show();
return a.exec();
}