Qtドラッグ&ドロップアシスタントクラス——Qtコントロールのドラッグ&ドロッププログラムの作成を簡略化
Qtプログラムでは、ドラッグ&ドロップ機能がよく使用されるため、ネット上の多くの例は、このクラスの2つの虚関数を直接書き換えるものです.
しかしながら、各コントロールは、コードの簡潔性を低下させ、書き換えであるため、上記2つの虚関数をヘッダファイルに暴露せざるを得ない.
だから、クラスを書いて、イベントフィルタでコードを簡略化できるかどうか、ずっと考えていました.
答えはいいです.
あまり話さないで、直接コードをつけます.
dragdrophelper.h:
dragdrophelper.cpp:
使用:(ドラッグアンドドロップの場合、処理を実行するオブジェクトはwidget、処理するスロット関数はloadFiles()と仮定)
これにより,文章の最初に言及した2つの虚関数を書き換えることがなくなり,スロット関数を1つ書くだけでよい.
さらに、イベントフィルタは動的にインストール/アンインストールでき、実行中に何らかの動作に応答するかどうかを選択できます.
protected:
virtual void dragEnterEvent(QDragEnterEvent *event) override;
virtual void dropEvent(QDropEvent *event) override;
しかしながら、各コントロールは、コードの簡潔性を低下させ、書き換えであるため、上記2つの虚関数をヘッダファイルに暴露せざるを得ない.
だから、クラスを書いて、イベントフィルタでコードを簡略化できるかどうか、ずっと考えていました.
答えはいいです.
あまり話さないで、直接コードをつけます.
dragdrophelper.h:
#ifndef DRAGDROPHELPER_H
#define DRAGDROPHELPER_H
#include
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include
#endif
class DragDropHelper : public QObject
{
Q_OBJECT
public:
enum AllowedType { None = 0, File = 1, Directory = 2, All = File | Directory };
Q_DECLARE_FLAGS(AllowedTypes, AllowedType)
explicit DragDropHelper(QWidget *beneficiary, AllowedTypes types = File);
void setAllowedTypes(AllowedTypes types);
signals:
void resourceDropped(const QList &urls);
private:
AllowedTypes types;
virtual bool eventFilter(QObject *watched, QEvent *event) override;
bool allResourceAllowed(const QList &urls);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(DragDropHelper::AllowedTypes)
#endif // DRAGDROPHELPER_H
dragdrophelper.cpp:
#include "dragdrophelper.h"
/*!
* \brief ,
* \details dragEnterEvent() dropEvent(),
* resourceDropped()
* \param beneficiary
* \param types , '|'
*/
DragDropHelper::DragDropHelper(QWidget *beneficiary, AllowedTypes types) : QObject(beneficiary)
{
this->types = types;
beneficiary->setAcceptDrops(true);
beneficiary->installEventFilter(this);
}
void DragDropHelper::setAllowedTypes(AllowedTypes types)
{
this->types = types;
}
bool DragDropHelper::eventFilter(QObject *watched, QEvent *event)
{
if ( event->type() == QEvent::DragEnter ) {
QDragEnterEvent *e = dynamic_cast(event);
if ( !e || !e->mimeData()->hasUrls() )
return QObject::eventFilter(watched, event);
if ( allResourceAllowed( e->mimeData()->urls() ) ) {
e->acceptProposedAction();
return true;
}
} else if ( event->type() == QEvent::Drop ) {
QDropEvent *e = dynamic_cast(event);
if ( e )
emit resourceDropped( e->mimeData()->urls() );
}
return QObject::eventFilter(watched, event);
}
bool DragDropHelper::allResourceAllowed(const QList &urls)
{
if ( urls.isEmpty() )
return false;
if ( types.testFlag(File) && types.testFlag(Directory) )
return true;
if ( types.testFlag(File) )
foreach (QUrl url, urls)
if ( !QFileInfo(url.toLocalFile()).isFile() )
return false;
if ( types.testFlag(Directory) )
foreach (QUrl url, urls)
if ( !QFileInfo(url.toLocalFile()).isDir() )
return false;
return true;
}
使用:(ドラッグアンドドロップの場合、処理を実行するオブジェクトはwidget、処理するスロット関数はloadFiles()と仮定)
DragDropHelper *dragDropHelper = new DragDropHelper(widget, DragDropHelper::File);
connect(dragDropHelper, SIGNAL(resourceDropped(QList)), widget, SLOT(loadFiles(QList)));
これにより,文章の最初に言及した2つの虚関数を書き換えることがなくなり,スロット関数を1つ書くだけでよい.
さらに、イベントフィルタは動的にインストール/アンインストールでき、実行中に何らかの動作に応答するかどうかを選択できます.