之前在工具系统中增加了插件系统,现在在插件中实现拖拽来生成子窗口。
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();
}