子类化QListWidget实现自定义拖拽功能.

来源:互联网 发布:纳什 数据库 编辑:程序博客网 时间:2024/06/01 10:15

我们经常会碰到这样的一个问题,我们想把其他地方选中的文本,直接通过拖拽移动到一个控件中,从而实现方便添加项的功能.
这里我们以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_OBJECTpublic:    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_OBJECTpublic:    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();}

这里写图片描述

原创粉丝点击