PyGobject(八十二)Drag and Drop

在部件之间进行拖放,一般需要设置一个拖动源(拖动什么部件),使用Gtk.Widget.drag_source_set()方法,设置一个拖动目标(部件拖放到什么地方),使用Gtk.Widget.drag_dest_set()方法。

有些部件提供了特殊的方法来替代这两个方法,如 Gtk.TreeView 和 Gtk.IconView,它们提供enable_model_drag_source(start_button_mask, targets, actions)来设置拖动源。

为了在源和目的地之间传输数据,需要在“drag-data-get” 和 “drag-data-received”信号中的Gtk.SelectionData变量中进行set和get数据

Drag信号

NameWhen it is emittedCommon Purpose
drag-beginUser starts a dragSet-up drag icon
drag-data-getWhen drag data is requested by the destinationTransfer drag data from source to destination
drag-data-deleteWhen a drag with the action Gdk.DragAction.MOVE is completedDelete data from the source to complete the ‘move’
drag-endWhen the drag is completeUndo anything done in drag-begin

Drop信号

NameWhen it is emittedCommon Purpose
drag-motionDrag icon moves over a drop areaAllow only certain areas to be dropped onto
drag-dropIcon is dropped onto a drag areaAllow only certain areas to be dropped onto
drag-data-receivedWhen drag data is received by the destinationTransfer drag data from source to destination

例子

这里写图片描述
代码:

#!/usr/bin/env python3
# Created by xiaosanyu at 16/6/16
# section 130
TITLE = "Drag and Drop"
DESCRIPTION = ""
import gi

gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GdkPixbuf

(TARGET_ENTRY_TEXT, TARGET_ENTRY_PIXBUF, TARGET_ENTRY_ALL) = range(3)
(COLUMN_TEXT, COLUMN_PIXBUF, COLUMN_NAME) = range(3)

DRAG_ACTION = Gdk.DragAction.COPY

atom_text = Gdk.atom_intern('UTF8_STRING', False)
atom_pixbuf = Gdk.atom_intern('image/png', False)
text_entry = Gtk.TargetEntry.new("UTF8_STRING", Gtk.TargetFlags.SAME_APP, TARGET_ENTRY_ALL)
pixbuf_entry = Gtk.TargetEntry.new("image/png", Gtk.TargetFlags.SAME_APP, TARGET_ENTRY_ALL)


class DragDropWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="Drag and Drop Demo")

        vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
        self.add(vbox)

        hbox = Gtk.Box(spacing=12)
        vbox.pack_start(hbox, True, True, 0)

        self.iconview = DragSourceIconView()
        self.drop_area = DropArea()

        hbox.pack_start(self.iconview, True, True, 0)
        hbox.pack_start(self.drop_area, True, True, 0)

        button_box = Gtk.Box(spacing=6)
        vbox.pack_start(button_box, True, False, 0)

        image_button = Gtk.RadioButton.new_with_label_from_widget(None,
                                                                  "Images")
        image_button.connect("toggled", self.add_image_targets)
        button_box.pack_start(image_button, True, False, 0)

        text_button = Gtk.RadioButton.new_with_label_from_widget(image_button,
                                                                 "Text")
        text_button.connect("toggled", self.add_text_targets)
        button_box.pack_start(text_button, True, False, 0)

        all_button = Gtk.RadioButton.new_with_label_from_widget(image_button,
                                                                "ALL")
        all_button.connect("toggled", self.add_all)
        button_box.pack_start(all_button, True, False, 0)

        # self.add_image_targets()

    def add_image_targets(self, button=None):
        if button is None or button.get_active():
            targets = Gtk.TargetList.new([])
            targets.add_image_targets(TARGET_ENTRY_PIXBUF, True)

            self.drop_area.drag_dest_set_target_list(targets)
            self.iconview.drag_source_set_target_list(targets)

    def add_text_targets(self, button=None):
        if button is None or button.get_active():
            self.drop_area.drag_dest_set_target_list(None)
            self.iconview.drag_source_set_target_list(None)

            self.drop_area.drag_dest_add_text_targets()
            self.iconview.drag_source_add_text_targets()

    def add_all(self, button=None):
        if button is None or button.get_active():
            targets = Gtk.TargetList.new([text_entry])
            self.drop_area.drag_dest_set_target_list(targets)
            self.iconview.drag_source_set_target_list(targets)
            print(targets.find(atom_text), targets.find(atom_pixbuf))


class DragSourceIconView(Gtk.IconView):
    def __init__(self):
        Gtk.IconView.__init__(self)
        self.set_text_column(COLUMN_TEXT)
        self.set_pixbuf_column(COLUMN_PIXBUF)

        model = Gtk.ListStore(str, GdkPixbuf.Pixbuf, str)
        self.set_model(model)
        self.add_item("Item 1", "image-missing")
        self.add_item("Item 2", "help-about")
        self.add_item("Item 3", "edit-copy")

        self.enable_model_drag_source(Gdk.ModifierType.BUTTON1_MASK, [],
                                      DRAG_ACTION)
        self.connect("drag-data-get", self.on_drag_data_get)

    def on_drag_data_get(self, widget, drag_context, data, info, time):
        selected_path = self.get_selected_items()[0]
        selected_iter = self.get_model().get_iter(selected_path)
        if info == TARGET_ENTRY_TEXT:
            text = self.get_model().get_value(selected_iter, COLUMN_TEXT)
            data.set_text(text, -1)
        elif info == TARGET_ENTRY_PIXBUF:
            pixbuf = self.get_model().get_value(selected_iter, COLUMN_PIXBUF)
            data.set_pixbuf(pixbuf)
        elif info == TARGET_ENTRY_ALL:
            text = self.get_model().get_value(selected_iter, COLUMN_TEXT)
            name = self.get_model().get_value(selected_iter, COLUMN_NAME)
            data.set(atom_text, 8, (text + ";" + name).encode())
            # print(data.set_text(text + ";" + name, -1))
            # print(data.set_pixbuf(pixbuf))

    def add_item(self, text, icon_name):
        pixbuf = Gtk.IconTheme.get_default().load_icon(icon_name, 16, 0)
        self.get_model().append([text, pixbuf, icon_name])


class DropArea(Gtk.IconView):
    def __init__(self):
        Gtk.IconView.__init__(self)
        self.set_text_column(COLUMN_TEXT)
        self.set_pixbuf_column(COLUMN_PIXBUF)

        self.model = Gtk.ListStore(str, GdkPixbuf.Pixbuf)
        self.set_model(self.model)
        self.model.append(["Drop something on me!", None])

        self.drag_dest_set(Gtk.DestDefaults.ALL, [], DRAG_ACTION)
        self.enable_model_drag_dest([], DRAG_ACTION)

        self.connect("drag-data-received", self.on_drag_data_received)

    def on_drag_data_received(self, widget, drag_context, x, y, data, info, time):

        if info == TARGET_ENTRY_TEXT:
            text = data.get_text()
            self.model[0][0] = text
            print("Received text: %s" % text)

        elif info == TARGET_ENTRY_PIXBUF:
            pixbuf = data.get_pixbuf()
            width = pixbuf.get_width()
            height = pixbuf.get_height()
            self.model[0][1] = pixbuf
            print("Received pixbuf with width %spx and height %spx" % (width, height))
        elif info == TARGET_ENTRY_ALL:
            text = data.get_text().split(";")
            # pixbuf = data.get_pixbuf()
            pixbuf = Gtk.IconTheme.get_default().load_icon(text[1], 16, 0)
            self.model[0][0] = text[0]
            self.model[0][1] = pixbuf


def main():
    win = DragDropWindow()
    win.connect("delete-event", Gtk.main_quit)
    win.show_all()
    Gtk.main()


if __name__ == "__main__":
    main()





代码下载地址:http://download.csdn.net/detail/a87b01c14/9594728

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sanxiaochengyu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值