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,特此記錄一下。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章