h5用什么網(wǎng)站來做推廣怎么推
Qt拖拽事件詳解及代碼實(shí)現(xiàn)
- 前言
- 項(xiàng)目描述
- 代碼結(jié)構(gòu)簡介
- 代碼詳解
前言
qt拖拽事件是一項(xiàng)非常常用并且非常好用的功能,拖拽實(shí)際上是一種信息傳遞的載體,其目的是將信息從一個(gè)對(duì)象傳遞給另一個(gè)對(duì)象。通過拖拽可以簡化文件打開或業(yè)務(wù)操作流程,qt初學(xué)者學(xué)會(huì)拖拽事件后就可以馬上開發(fā)出許多有趣的項(xiàng)目,本文以一個(gè)簡單的示例來介紹拖拽事件功能。
項(xiàng)目描述
本項(xiàng)目通過搭建兩個(gè)對(duì)話框,一個(gè)作為拖拽信息來源,另一個(gè)作為拖拽信息目標(biāo),介紹拖拽事件,主要實(shí)現(xiàn)了字符串信息的傳遞,并且對(duì)拖拽過程的動(dòng)作進(jìn)行了探索。
代碼結(jié)構(gòu)簡介
DragDropWidget類實(shí)現(xiàn)了拖拽發(fā)起對(duì)話框,主要是重寫了鼠標(biāo)事件函數(shù),用于設(shè)置拖拽搭載的信息,這里就是一個(gè)字符串,實(shí)際上也可以是自定義的類或者其他對(duì)象。代碼詳見dragdropwidget.h及dragdropwidget.cpp。
AcceptWidget類實(shí)現(xiàn)了拖拽接收對(duì)話框,主要重寫了拖拽進(jìn)入及拖拽放置函數(shù),用于處理拖拽進(jìn)入的信息。代碼詳見acceptwidget.h及acceptwidget.cpp。
代碼詳解
dragdropwidget.h
#ifndef DRAGDROPWIDGET_H
#define DRAGDROPWIDGET_H#include <QWidget>class DragDropWidget : public QWidget
{Q_OBJECTpublic:DragDropWidget(QWidget *parent = 0);~DragDropWidget();protected:void mousePressEvent(QMouseEvent *event) override;void mouseMoveEvent(QMouseEvent *event) override;void mouseReleaseEvent(QMouseEvent *event) override;
private:QPoint m_DragStartPos;
};#endif // DRAGDROPWIDGET_H
在DragDropWidget 類的頭文件中聲明了經(jīng)典鼠標(biāo)處理三事件,并聲明了一個(gè)成員變量m_DragStartPos,用于記錄拖拽的起始位置。
dragdropwidget.cpp
#include "dragdropwidget.h"#include <QStyle>
#include <QStyleOption>
#include <QIcon>
#include <QDrag>
#include <QMimeData>
#include <QMouseEvent>
#include <QApplication>#include <QLabel>
#include <QDebug>DragDropWidget::DragDropWidget(QWidget *parent): QWidget(parent)
{m_DragStartPos=QPoint(-1,-1);setWindowTitle("dragwidget");
}DragDropWidget::~DragDropWidget()
{}void DragDropWidget::mousePressEvent(QMouseEvent *event)
{if(event->button()==Qt::LeftButton){m_DragStartPos=event->pos();printf("====mousepressed\n");}
}void DragDropWidget::mouseMoveEvent(QMouseEvent *event)
{if (event->buttons() & Qt::LeftButton){if(QLineF(event->pos(),m_DragStartPos).length()<QApplication::startDragDistance()){printf("distence less\n");return;}printf("===process drag\n");QDrag *drag=new QDrag(this);QMimeData *mimedata=new QMimeData;mimedata->setData("localtype","teststr");drag->setMimeData(mimedata);QStyle *style = QApplication::style();QStyleOption option;QIcon icon = style->standardIcon(QStyle::SP_DialogOpenButton, &option, nullptr);QPixmap pixmap = icon.pixmap(32, 32);drag->setPixmap(pixmap);drag->setHotSpot(QPoint(10,10));Qt::DropAction dropaction=drag->exec(Qt::CopyAction); //| Qt::MoveAction}
}void DragDropWidget::mouseReleaseEvent(QMouseEvent *event)
{QWidget::mouseReleaseEvent(event);
}
在構(gòu)造函數(shù)中,對(duì)拖拽起始位置進(jìn)行了初始化,并設(shè)置了窗口名稱;在mousePressEvent函數(shù)中,判斷了是否為左鍵點(diǎn)擊,并更新了拖拽起始位置;在mouseMoveEvent函數(shù)中,首先判斷拖拽事件中左鍵是否在移動(dòng)中保持了點(diǎn)擊狀態(tài),
if (event->buttons() & Qt::LeftButton)
event->buttons()獲取在移動(dòng)過程中的所有保持點(diǎn)擊狀態(tài)的按鈕,和Qt::LeftButton做&運(yùn)算,用于判斷左鍵是否在這些按鈕中,據(jù)此判斷左鍵是否在移動(dòng)中保持點(diǎn)擊狀態(tài);
if(QLineF(event->pos(),m_DragStartPos).length()<QApplication::startDragDistance())
通過判斷當(dāng)前鼠標(biāo)所在位置與起始拖拽點(diǎn)之間的距離是否超過一定范圍來判斷拖拽是否有效,QApplication::startDragDistance()為10px;
QDrag *drag=new QDrag(this);QMimeData *mimedata=new QMimeData;
首先構(gòu)造了QDrag及QMimeData對(duì)象;
mimedata->setData("localtype","teststr");
然后對(duì)QMimeData對(duì)象設(shè)置了數(shù)據(jù),這里setData有兩個(gè)參數(shù),這里用的是通用的數(shù)據(jù)設(shè)置綁定方法,第一個(gè)參數(shù)“l(fā)ocaltype”為設(shè)置的數(shù)據(jù)類型,這里可以自定義一個(gè)字符串作為類型,第二個(gè)參數(shù)即為傳遞的數(shù)據(jù),第二個(gè)參數(shù)的類型為QByteArray,也就是說,傳進(jìn)來的內(nèi)容將會(huì)被轉(zhuǎn)為QByteArray類型,后續(xù)在解析時(shí)可以將QByteArray還原為傳入的類型。
drag->setMimeData(mimedata);
這里將QMimeData對(duì)象綁定到QDrag對(duì)象,借助QDrag對(duì)象實(shí)現(xiàn)數(shù)據(jù)的傳遞;
QStyle *style = QApplication::style();QStyleOption option;QIcon icon = style->standardIcon(QStyle::SP_DialogOpenButton, &option, nullptr);QPixmap pixmap = icon.pixmap(32, 32);drag->setPixmap(pixmap);drag->setHotSpot(QPoint(10,10));
這里實(shí)際上是對(duì)QDrag對(duì)象設(shè)置一個(gè)圖標(biāo),用于在拖拽過程中顯示,這里使用了qt內(nèi)置的標(biāo)準(zhǔn)圖標(biāo),setHotSpot函數(shù)用于指定拖拽點(diǎn)位于圖標(biāo)的位置;
Qt::DropAction dropaction=drag->exec(Qt::CopyAction);
最后執(zhí)行了QDrag對(duì)象的exec函數(shù),這里可以指定拖拽動(dòng)作類型,不同的類型會(huì)影響后面在接收拖拽時(shí)的顯示,例如Qt::CopyAction在接收拖拽時(shí)則會(huì)在之前設(shè)置的圖標(biāo)右下角顯示一個(gè)“+”號(hào);
acceptwidget.h
#ifndef ACCEPTWIDGET_H
#define ACCEPTWIDGET_H#include <QWidget>class QDragEnterEvent;
class QDropEvent;class AcceptWidget : public QWidget
{Q_OBJECT
public:explicit AcceptWidget(QWidget *parent = nullptr);
protected:void dragEnterEvent(QDragEnterEvent *event) override;void dropEvent(QDropEvent *event) override;signals:public slots:
};#endif // ACCEPTWIDGET_H
AcceptWidget 類的頭文件中聲明了處理接收拖拽事件的dragEnterEvent及dropEvent函數(shù),這兩個(gè)函數(shù)是處理接收拖拽事件最基本的兩個(gè)函數(shù),dragEnterEvent用于處理進(jìn)入本窗口時(shí)需要做出的操作,例如判斷拖拽進(jìn)入的內(nèi)容是否需要接受等,dropEvent函數(shù)用于處理確認(rèn)接收拖拽事件的操作,主要是獲取QMimeData;
acceptwidget.cpp
#include "acceptwidget.h"#include <QStyle>
#include <QStyleOption>
#include <QIcon>
#include <QLabel>
#include <QMimeData>
#include <QDropEvent>
#include <QDragEnterEvent>
#include <QApplication>AcceptWidget::AcceptWidget(QWidget *parent) : QWidget(parent)
{setWindowTitle("Drop Widget");this->setAcceptDrops(true);
}void AcceptWidget::dragEnterEvent(QDragEnterEvent *event)
{event->acceptProposedAction();printf("drag enter\n");
}void AcceptWidget::dropEvent(QDropEvent *event)
{printf("grop enter\n");const QMimeData *mimedata= event->mimeData();if(mimedata->hasFormat("localtype")){QByteArray mimestr=mimedata->data("localtype");std::string sstr=mimestr.toStdString();printf("=====sstring==%s\n",sstr.c_str());QLabel *label=new QLabel(this);QStyle *style = QApplication::style();QStyleOption option;QIcon icon = style->standardIcon(QStyle::SP_DialogOpenButton, &option, nullptr);QPixmap pixmap = icon.pixmap(32, 32);label->setPixmap(pixmap);label->move(event->pos());label->show();}
}
AcceptWidget 類的源文件主要代碼在dropEvent函數(shù)中,當(dāng)然首先需要在構(gòu)造函數(shù)中開啟接收拖拽事件的標(biāo)識(shí)通過setAcceptDrops(true),來標(biāo)識(shí)本窗口接收拖拽事件;
event->acceptProposedAction();
在dragEnterEvent函數(shù)中確認(rèn)接受拖拽事件的動(dòng)作,這樣拖拽事件才能進(jìn)入dropEvent函數(shù);
const QMimeData *mimedata= event->mimeData();
在dropEvent函數(shù)中直接通過QDropEvent 即可獲取拖拽事件傳遞來的QMimeData 對(duì)象;
if(mimedata->hasFormat("localtype"))
首先對(duì)傳遞來的QMimeData 對(duì)象進(jìn)行類型判斷,使用hasFormat函數(shù),這里的類型參數(shù)即為拖拽事件產(chǎn)生窗口中設(shè)置的參數(shù);
QByteArray mimestr=mimedata->data("localtype");std::string sstr=mimestr.toStdString();
首先根據(jù)類型從QMimeData 對(duì)象中獲取QByteArray 格式的數(shù)據(jù),然后通過轉(zhuǎn)換,恢復(fù)為原始類型,這里傳遞的是字符串類型,最終恢復(fù)為字符串類型;
QLabel *label=new QLabel(this);QStyle *style = QApplication::style();QStyleOption option;QIcon icon = style->standardIcon(QStyle::SP_DialogOpenButton, &option, nullptr);QPixmap pixmap = icon.pixmap(32, 32);label->setPixmap(pixmap);label->move(event->pos());label->show();
后面為了拖拽事件更有趣味,在窗口中用Qlabel顯示了許多圖標(biāo)。
main.cpp
#include <QApplication>#include "dragdropwidget.h"
#include "acceptwidget.h"int main(int argc, char *argv[])
{QApplication a(argc, argv);DragDropWidget w;w.show();AcceptWidget aw;aw.move(800,0);aw.show();return a.exec();
}
demo.pro
QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = DragDropDemo
TEMPLATE = appDEFINES += QT_DEPRECATED_WARNINGSSOURCES += \main.cpp \dragdropwidget.cpp \acceptwidget.cppHEADERS += \dragdropwidget.h \acceptwidget.hMOC_DIR = ./moc
OBJECTS_DIR = ./moc