Python with GTK 3 Drag and Drop

今回は Python with GTK+ 3 で Drag and Drop をやってみる。
といってもファイルドロップで URI を得るというよく利用するものだけだが。

Drag and Drop

何か色々と細かくなったような気がするけどあまり変わっていなかった。
drag_dest_set() で text/uri-list を指定するだけでドロップ受け入れ処理は終わり。

ただし GtkTargetEntry は new で作成し list にして渡す必要があった。
PyGtk の場合はタプルのリストで良かったので少しだけ面倒くさくなった。
やはり C で書くのとも PyGtk で書くのとも微妙に違っていて迷う。

ところで drag-data-received シグナルのハンドラなんだが

def on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
    """
    PyGtk
    if "\r\n" in data.data:
        uris = data.data.split("\r\n")
    else:
        uris = data.data.split("\n")
    """
    # Python with GTK+ 3
    uris = data.get_uris()

と get_uris() だけで list が得られるようになっている。
これで送られてくる uri-list の改行コードを気にしなくて済む。

それと前やった時には何故か気がつかなかったのだけど
GtkApplication にセットする方法なら delete-event 処理は不要なんだね。
Delphi の TApplication のように全ての Window を閉じた時点で終了するようだ。

ついでに以前 PyGtk でやった content-type を得る方法も入れてと。
というか、ソレらをやらないと Y901x の GTK3 化ができない。

後は GTK+ 3 に合わせて書き換えていく。

#!/usr/bin/env python
#-*- coding:utf-8 -*-

import sys
import gi
try:
    gi.require_version("Gtk", "3.0")
except:
    print "This Program is GTK+ 3.0 or later."
    sys.exit()

from gi.repository import Gtk, Gdk, Gio

class Win(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        # DnD
        dnd_list = Gtk.TargetEntry.new("text/uri-list", 0, 0)
        self.drag_dest_set(
                Gtk.DestDefaults.MOTION |
                Gtk.DestDefaults.HIGHLIGHT |
                Gtk.DestDefaults.DROP,
                [dnd_list],
                Gdk.DragAction.MOVE )
        # GtkLabel
        self.label = Gtk.Label("Please drop your files")
        self.add(self.label)
        # Gtk.Window
        self.drag_dest_add_uri_targets()
        self.connect("drag-data-received", self.on_drag_data_received)
        self.set_title("dnd_type")
        self.show_all()

    def on_drag_data_received(self, widget, drag_context, x, y, data, info, time):
        uris = data.get_uris()
        s = ""
        for uri in uris:
            f = Gio.file_new_for_uri(uri)
            info = f.query_info(
                    Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
                    Gio.FileQueryInfoFlags.NONE,
                    None)
            content_type = info.get_content_type()
            s += "URI={0}\nContent Type={1}\n".format(uri, content_type)
        self.label.set_text(s)

class App(Gtk.Application):
    def __init__(self):
        Gtk.Application.__init__(
                self,
                application_id="apps.test.trash",
                flags=Gio.ApplicationFlags.FLAGS_NONE)
        self.connect("activate", self.on_activate)
        
    def on_activate(self, application, user_data=None):
        w = Win()
        # Gtk.main_quit is Do not Need
        w.set_application(self)
    
if __name__ == "__main__":
    app = App()
    app.run(sys.argv)

情報が少ないなりにマシになったと思う。
日本語で検索してもまったく情報が見当たらないんだが需要はそんなに無いのかな…

**********

CNN.co.jp:ユーザーのIQが高いブラウザーは? ブラウザー別IQテスト

比較的どころかまったく人気が無い Linux 版 Opera な私は IQ が極めて高い。
わけが無い、工業高校機械化卒な現場のオッサンだもの。