2012年1月28日土曜日

( Qt C++ )メインウィンドウでドラッグ&ドロップを受け付ける


はいそれでは新しい章「Drag and Drop」をやっていきます。
C++ GUI Programming with Qt4ですと205ページからの章です。

今回はまずメインウィンドウへのドラッグ&ドロップについてやっていきます。

サンプルはC++ GUI Programming with Qt4ですと205ページからのものを少し改変し使用します。
そして、いつものようにQtCreaterの使用を前提とします。(QtCreaterなどの使い方は ”Qtをはじめよう" を見てください。)
ではコードを


(mainwindow.h)
#include <QMainWindow>
#include <QDropEvent>
#include <QUrl>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT//マクロ
    
public:
    explicit MainWindow(QWidget *parent = 0);//コンストラクタ
    ~MainWindow();//デストラクタ
    void dragEnterEvent(QDragEnterEvent *e);//----ここ重要!
    void dropEvent(QDropEvent *e);//----ここ重要!
    
private:
    Ui::MainWindow *ui;//uiにはGUI部品関連の記述
};

(mainwindow.cpp)
#include "mainwindow.h"
#include "ui_mainwindow.h"

//コンストラクタ
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)//uiにはGUI部品に関する記述
{
    ui->setupUi(this);//uiのGUI部品初期化

    //重要!ドラックandドロップを受け付ける
    //ように設定する。(trueで受け付ける)
    setAcceptDrops(true);
}

MainWindow::~MainWindow()//デストラクタ
{
    delete ui;
}

void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
    if(e->mimeData()->hasFormat("text/uri-list"))
    {
        //視覚的にドロップを受付られることを
        //表示し、ドラッグ&ドロップを受け付ける
        //これがないと受付られない。
        e->acceptProposedAction();
    }
}

void MainWindow::dropEvent(QDropEvent *e)
{
    //dragEnterEventの後にくるイベント
    //ドロップの際の動作を記述する
    ui->label->setText(
                e->mimeData()->urls().first().toLocalFile());
}

はい簡単ですね。uiは今回の理解にはあまり関係ないので無視します。

まずヘッダ部で重要なのはdragEnterEvent、dropEventをオーバーライドすることを宣言する部分です。あとは見たまんまです。

次に.cppですがまずコンストラクタでsetAcceptDrops(true);を記述しています。
これはドラック&ドロップを許可するように設定しています。許可する場合は必ず書いてください。
なおsetAcceptDrops(false);を記述するとドラック&ドロップは禁止されます。
(デフォルトでドラック&ドロップ許可のウィジットもあります。これは各ウィジット、リファレンスで確認してください。)

次にdragEnterEventの実装ですが引数のeにドラック&ドロップされたファイルの情報が格納されます。そこからMIMEデータを取り出しそのタイプをhasFormatでチェックしています。
今回はtext/uri-listであるかどうかをチェックし、そうならばe->acceptProposedAction();を記述しドラック&ドロップを許可するようにしています。
(QDragEnterEventリファレンス)(QMimeDataリファレンス)

次にdropEventですが、これはdragEnterEventでドラック&ドロップを許可された場合に呼び出されます。これも引数のeにドラック&ドロップされたファイルの情報が格納されますのでそこからMIMEデータを取り出して、そのファイルパスをQLabelに表示しています。
(QDropEventリファレンス)(QMimeDataリファレンス)

※なお正式なMIMEリストはこちら(英語)です。


これらを実行すると以下のようになります。(画像はファイルシステム直下のvmlinuzファイルをドラック&ドロップしたところ。)



以上です。