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

本文介绍如何通过自定义QListWidget实现文本项的拖拽功能,包括从外部拖拽文本进入QListWidget以及在不同QListWidget间拖拽项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

这里写图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值