QT 实现通过拖拽动态生成子窗口

之前在工具系统中增加了插件系统,现在在插件中实现拖拽来生成子窗口。

2023-09-08 09-49-10

先介绍会用到的一些基本知识 

QApplication提供了两个拖放相关的方法:

1. QApplication::startDragTime。它描述了用户按下鼠标多长时间开始拖放操作。

2. QApplication::startDragDistance。它描述了用户按下鼠标移动多少像素才开始拖动。默认的是4个像素。

拖动操作drag:为了开始一个拖动操作,需要创建一个QDrag对象,然后调用exec()函数

QMimeData:是记录MIME类型信息的类,标准的MIME类型是有国际因特网地址分配委员会定义的,由类型,子类型信息和分隔两者的斜线组成。MIME通常由剪贴板和拖放系统使用。QMimeData提供了一些可以用于处理最常见的拖动信息(例如图像,URL,颜色,纯文本,超文本)。setText()设置文本信息。将QMimeData对象存储在QDrag对象里,并设置了随光标移动的拖动图片setPixmap()。QDrag::exec()启动拖动操作。

从一个widget (DropTreeWidget)中开始拖动,在另外(WorkerMdiArea)一个中放下。

在DropTreeWidget中重写两个Event



void DropTreeWidget::mousePressEvent(QMouseEvent * event)
{
   QTreeWidget::mousePressEvent(event);
   if(event->button()==Qt::LeftButton)
   {
       startPos =event->pos();
       qDebug()<<"mousePressEvent";
   }
}

void DropTreeWidget::mouseMoveEvent(QMouseEvent * event)
{
    QTreeWidget::mouseMoveEvent(event);
    if(event->buttons()&Qt::LeftButton)
    {
        int distance =(event->pos()-startPos).manhattanLength();
        qDebug()<<"distance:"<<distance;
        if(distance>=QApplication::startDragDistance())
        {
           qDebug()<<"mouseMoveEvent";
           performDrag();
        }
    }
}

 performDrag()中来完成拖拽的动作

void DropTreeWidget::performDrag()
{
    QTreeWidgetItem *item=this->currentItem();

    if(item ==NULL)
    {
       return ;
    }

    QPixmap pixmap(256,32);
    pixmap.fill(Qt::transparent);

    QPainter painter(&pixmap);
    painter.drawPixmap(0,0,32,32,item->icon(0).pixmap(QSize(32,32)));
    painter.drawText(QRect(32,0,200,32),item->text(0));

    QMimeData *mimeData = new QMimeData();

    mimeData->setText(item->text(0));
  //  mimeData->setData("test","pirates");

    QDrag *drag = new QDrag(this);

    drag->setMimeData(mimeData);
    drag->setPixmap(pixmap);
    drag->exec(Qt::MoveAction);

    qDebug()<<"performDrag";

    delete drag;

}

WorkerMdiArea中重写两个Event,并且要设置 this->setAcceptDrops(true);

void WorkerMdiArea::dropEvent(QDropEvent *event)
{
      qDebug()<<"dropEvent1";
   QMdiArea::dropEvent(event);
   const QMimeData * mimeData =(const QMimeData *)event->mimeData();

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


   if(mimeData->text()=="Item 1")
   {
     QWidget * pPlug = new QWidget();
     pPlug->setWindowTitle(mimeData->text());
     this->addSubWindow(pPlug);

     pPlug->show();
     event->setDropAction((Qt::MoveAction));
     event->accept();
     qDebug()<<"dropEvent";
   }

}
void WorkerMdiArea::dragEnterEvent(QDragEnterEvent *event)
{
   qDebug()<<"dragEnterEvent";
   QMdiArea::dragEnterEvent(event);
   event->accept();
}
完整的代码:
droptreewidget.h
#ifndef DROPTREEWIDGET_H
#define DROPTREEWIDGET_H

#include <QObject>
#include<QTreeWidget>
#include<QPoint>
#include<QMouseEvent>

class DropTreeWidget : public QTreeWidget
{
    Q_OBJECT
public:
    DropTreeWidget(QWidget*parent);

protected:
    QPoint startPos;
    void mousePressEvent(QMouseEvent * event);
    void mouseMoveEvent(QMouseEvent * event);

    void performDrag();

};

#endif // DROPTREEWIDGET_H

 droptreewidget.cpp

#include "droptreewidget.h"
#include<QApplication>
#include<QDebug>
#include<QPainter>
#include<QMimeData>
#include<QDrag>

DropTreeWidget::DropTreeWidget(QWidget*parent):QTreeWidget(parent)
{
  this->setAcceptDrops(false);
  this->setDragEnabled(false);
  this->setHeaderHidden(true);
    QTreeWidgetItem *item1 = new QTreeWidgetItem(this);
    item1->setText(0, "Item 1");
    QIcon icon(":/icon/init.png");
    item1->setIcon(0,icon);
}


void DropTreeWidget::mousePressEvent(QMouseEvent * event)
{
   QTreeWidget::mousePressEvent(event);
   if(event->button()==Qt::LeftButton)
   {
       startPos =event->pos();
       qDebug()<<"mousePressEvent";
   }
}

void DropTreeWidget::mouseMoveEvent(QMouseEvent * event)
{
    QTreeWidget::mouseMoveEvent(event);
    if(event->buttons()&Qt::LeftButton)
    {
        int distance =(event->pos()-startPos).manhattanLength();
        qDebug()<<"distance:"<<distance;
        if(distance>=QApplication::startDragDistance())
        {
           qDebug()<<"mouseMoveEvent";
           performDrag();
        }
    }
}

void DropTreeWidget::performDrag()
{
    QTreeWidgetItem *item=this->currentItem();

    if(item ==NULL)
    {
       return ;
    }

    QPixmap pixmap(256,32);
    pixmap.fill(Qt::transparent);

    QPainter painter(&pixmap);
    painter.drawPixmap(0,0,32,32,item->icon(0).pixmap(QSize(32,32)));
    painter.drawText(QRect(32,0,200,32),item->text(0));

    QMimeData *mimeData = new QMimeData();

    mimeData->setText(item->text(0));
  //  mimeData->setData("test","pirates");

    QDrag *drag = new QDrag(this);

    drag->setMimeData(mimeData);
    drag->setPixmap(pixmap);
    drag->exec(Qt::MoveAction);

    qDebug()<<"performDrag";

    delete drag;

}
workermdiarea.h
#ifndef WORKERMDIAREA_H
#define WORKERMDIAREA_H

#include <QObject>
#include<QMdiArea>
#include<QMimeData>
#include<QDropEvent>
#include<QDebug>

class WorkerMdiArea : public QMdiArea
{
    Q_OBJECT
public:
    WorkerMdiArea();

    void dropEvent(QDropEvent *event);
    void dragEnterEvent(QDragEnterEvent *event);

};

#endif // WORKERMDIAREA_H

workermdiarea.cpp

#include "workermdiarea.h"

WorkerMdiArea::WorkerMdiArea()
{
   this->setAcceptDrops(true);
}

void WorkerMdiArea::dropEvent(QDropEvent *event)
{
      qDebug()<<"dropEvent1";
   QMdiArea::dropEvent(event);
   const QMimeData * mimeData =(const QMimeData *)event->mimeData();

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


   if(mimeData->text()=="Item 1")
   {
     QWidget * pPlug = new QWidget();
     pPlug->setWindowTitle(mimeData->text());
     this->addSubWindow(pPlug);

     pPlug->show();
     event->setDropAction((Qt::MoveAction));
     event->accept();
     qDebug()<<"dropEvent";
   }

}
void WorkerMdiArea::dragEnterEvent(QDragEnterEvent *event)
{
   qDebug()<<"dragEnterEvent";
   QMdiArea::dragEnterEvent(event);
   event->accept();
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值