Qt之drag and drop

Qt Designer 的出现,让我们很容易通过控件的方式设计出我们自己的软件界面。但有时,Designer提供给我们的控件,无法满足我们的需求,需要根据实际情况采取继承的方式进行设计。

本文通过QListWidget和QTreeWidget之间的拖曳进行说明。

工程文件

1个工程文件

3个头文件

4个源文件

1个form文件

如图


各文件源码

1.根据实际情况,创建类

//qlistwidget_ex.h
#ifndef QLISTWIDGET_EX_H
#define QLISTWIDGET_EX_H

#include <QListWidget>
#include <QPoint>
#include <QMouseEvent>


class QListWidget_ex : public QListWidget
{
    Q_OBJECT
public:
    QListWidget_ex();
protected:
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *e);

private:
    QPoint m_beginPos;
};

#endif // QLISTWIDGET_EX_H

//qlistwidget_ex.cpp
#include "qlistwidget_ex.h"

#include <QDrag>
#include <QMimeData>
#include <QDebug>
#include <QImage>
#include <QApplication>

QListWidget_ex::QListWidget_ex()
{
}
void QListWidget_ex::mousePressEvent(QMouseEvent *event)
{
    if(event->button()==Qt::LeftButton)
    {
        m_beginPos=event->pos();
        //qDebug()<<m_beginPos.rx()<<"+"<<m_beginPos.ry();
    }
    QListWidget::mousePressEvent(event);
}
void QListWidget_ex::mouseMoveEvent(QMouseEvent *e)
{
    if(e->buttons()&Qt::LeftButton)
    {
        int nDistance=(e->pos()-m_beginPos).manhattanLength();
        if(nDistance>=QApplication::startDragDistance())
        {
          //  qDebug()<<nDistance;
            QListWidgetItem *item=currentItem();
            if(item)
            {
                QMimeData *mimeData=new QMimeData;
                mimeData->setText(item->text());

            //    qDebug()<<mimeData->text();

                QDrag *drag=new QDrag(this);
                drag->setMimeData(mimeData);
                QImage image;//(128,128,QImage::Format_ARGB32);
                if(image.load("../images/qt.png")==true)
                    drag->setPixmap(QPixmap::fromImage(image));

                if(Qt::MoveAction==drag->exec(Qt::MoveAction))
                {
                    delete item;
                   // qDebug()<<"delete item";
                }
            }
        }
    }
    QListWidget::mouseMoveEvent(e);
}

//qtreewidget_ex.h
class Qtreewidget_ex : public QTreeWidget
{
    Q_OBJECT
public:
    explicit Qtreewidget_ex();
protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dropEvent(QDropEvent *event);
};

//qtreewidget_ex.cpp
Qtreewidget_ex::Qtreewidget_ex()
{
    setAcceptDrops(true);
}
void Qtreewidget_ex::dragEnterEvent(QDragEnterEvent *event)
{
    QListWidget_ex *source=qobject_cast<QListWidget_ex*>(event->source());
    if(source)
    {
        event->setDropAction(Qt::MoveAction);
        event->accept();
        //qDebug()<<source;
    }
}
void Qtreewidget_ex::dragMoveEvent(QDragMoveEvent *event)
{
    QListWidget_ex *source=qobject_cast<QListWidget_ex*>(event->source());
    if(source)
    {
        event->setDropAction(Qt::MoveAction);
        event->accept();
    }
}
void Qtreewidget_ex::dropEvent(QDropEvent *event)
{
    QListWidget_ex *source=qobject_cast<QListWidget_ex*>(event->source());
    if(source)
    {
        QModelIndex currentId=indexAt(event->pos());
        if(currentId.isValid())
        {
            QTreeWidgetItem *item=itemFromIndex(currentId);
            model()->insertRow(item->childCount(),currentId);
            QModelIndex childId=model()->index(item->childCount()-1,0,currentId);
            model()->setData(childId,QVariant(event->mimeData()->text()),Qt::DisplayRole);
            event->setDropAction(Qt::MoveAction);
            event->accept();
        }
    }
}

2.写MainWindow.cpp文件

//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QGridLayout>
#include <QHBoxLayout>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)

{
    ui->setupUi(this);
    m_listWidget=new QListWidget_ex;
    m_treeWidget=new Qtreewidget_ex;

    QWidget *centerWindow = new QWidget;
    this->setCentralWidget(centerWindow);

    QHBoxLayout *hLayout=new QHBoxLayout;

    m_listWidget->addItem("drag1");
    m_listWidget->addItem("drag2");
    m_listWidget->addItem("drag3");

    QTreeWidgetItem *item=new QTreeWidgetItem(QStringList(QString("first")));
    QTreeWidgetItem *item2=new QTreeWidgetItem(QStringList(QString("second")));

    m_treeWidget->setHeaderLabel("treeWidget");
    m_treeWidget->addTopLevelItem(item);
    m_treeWidget->addTopLevelItem(item2);


    hLayout->addWidget(m_listWidget);
    hLayout->addWidget(m_treeWidget);

    centerWindow->setLayout(hLayout);

}

MainWindow::~MainWindow()
{
    delete ui;
}

3.由于重写了控件,main.cpp保存原样即可

//main.cpp
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    
    return a.exec();
}

程序截图

小结

由于本人当时对Qt的理解不够,没明白如何添加相应的控件到UI,特此记录一下。



  • 文章声明
  • 作者:Owen
  • 出处: http://www.cnblogs.com/owenyang
  • 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该博客同步发在 HEXO-博客
  • 原文地址:https://www.cnblogs.com/owenyang/p/3579067.html