Paepoi

Paepoi » GTK4(Python) Tips » GTK4(Python) Tips | コントローラー

GTK4(Python) Tips | コントローラー

# 最終更新日 2023.05.14

ファイルのドロップ
GTK4 でファイルマネージャからのファイルドロップを受け入れる方法。
#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gdk

class Win(Gtk.ApplicationWindow):
    def __init__(self, a):
        manager = Adw.StyleManager.get_default()
        manager.set_color_scheme(Adw.ColorScheme.DEFAULT)
        Gtk.ApplicationWindow.__init__(self, application=a)
        # Drag and Drop
        drop_target = Gtk.DropTarget.new(Gdk.FileList, Gdk.DragAction.COPY)
        drop_target.connect('accept', self.on_drop_accept)
        drop_target.connect('drop', self.on_file_drop)
        self.add_controller(drop_target)
        # label
        self.uri_label = Gtk.Label(label='ドロップしてください')
        self.set_child(self.uri_label)
        self.set_default_size(200, 100)

    def on_drop_accept(self, target, drop):
        '''
            True を戻すと受け入れますが文字列のドロップ等も対象になる
            ファイルマネージャからのドロップのみにするには下記
        '''
        fmt = drop.get_formats()
        if fmt.contain_gtype(Gdk.FileList):
            return True
        return False

    def on_file_drop(self, target, value, x, y):
        '''
            value は Gdk.FileList
        '''
        files = value.get_files()
        ls = [ f.get_basename() for f in files]
        self.uri_label.set_text('\n'.join(ls))

app = Gtk.Application()
app.connect('activate', lambda a: Win(a).present())
app.run()
drop_file.webp

文字列のドロップ
Gedit や Evince 等 GNOME Applikation の文字列ドロップを受け入れる。
Google Chrome 等サードパーティには対応していないので注意。
#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gdk

class Win(Gtk.ApplicationWindow):
    def __init__(self, a):
        manager = Adw.StyleManager.get_default()
        manager.set_color_scheme(Adw.ColorScheme.DEFAULT)
        Gtk.ApplicationWindow.__init__(self, application=a)
        # Drag and Drop
        drop_target = Gtk.DropTarget.new(str, Gdk.DragAction.COPY)
        drop_target.connect('accept', self.on_drop_accept)
        drop_target.connect('drop', self.on_text_drop)
        self.add_controller(drop_target)
        # label
        self.uri_label = Gtk.Label(label='ドロップしてください')
        self.set_child(self.uri_label)
        self.set_default_size(200, 100)

    def on_drop_accept(self, target, drop):
        '''
            ファイルマネージャからのドロップもパス名の文字列で渡ってくる
            それを弾くには以下のようにする
        '''
        fmt = drop.get_formats()
        if fmt.contain_mime_type('UTF8_STRING'):
            return True
        return False

    def on_text_drop(self, drop, value, x, y):
        '''
            この場合 value は文字列になる
        '''
        self.uri_label.set_text(value)

app = Gtk.Application()
app.connect('activate', lambda a: Win(a).present())
app.run()
drop_text.webp

マウスクリックの検知
クリックすると位置を表示、ダブルクリックは Double Click と表示させます。
タイトルバー領域も対象となるので戸惑わないでください。
#!/usr/bin/env python3

import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gdk

class Win(Gtk.ApplicationWindow):
    def __init__(self, a):
        manager = Adw.StyleManager.get_default()
        manager.set_color_scheme(Adw.ColorScheme.DEFAULT)
        Gtk.ApplicationWindow.__init__(self, application=a)
        # Click
        controller_click = Gtk.GestureClick()
        controller_click.connect('pressed', self.on_cllick_pressed)
        self.add_controller(controller_click)
        # label
        self.xy_label = Gtk.Label(label='x= y=')
        self.set_child(self.xy_label)
        self.set_default_size(200, 200)

    def on_cllick_pressed(self, widget, n_press, x, y):
        '''
            クリックすると位置を表示
            ダブルクリックは Double Click と表示
        '''
        if n_press == 2:
            self.xy_label.set_text('Double Click')
        else:
            self.xy_label.set_text(f'x={round(x)} y={round(y)}')

app = Gtk.Application()
app.connect('activate', lambda a: Win(a).present())
app.run()
click.webp

マウスオーバーの検知
ウインドウ上でマウスを動かした場合のみ検知します。
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, Gdk

class Win(Gtk.ApplicationWindow):
    def __init__(self, a):
        manager = Adw.StyleManager.get_default()
        manager.set_color_scheme(Adw.ColorScheme.DEFAULT)
        Gtk.ApplicationWindow.__init__(self, application=a)
        # mouse move
        controller_motion = Gtk.EventControllerMotion()
        controller_motion.connect('motion', self.on_mouse_motion)
        self.add_controller(controller_motion)
        # label
        self.xy_label = Gtk.Label(label='x= y=')
        self.set_child(self.xy_label)
        self.set_default_size(200, 200)

    def on_mouse_motion(self, widget, x,y):
        self.xy_label.set_text(f'x={round(x)} y={round(y)}')

app = Gtk.Application()
app.connect('activate', lambda a: Win(a).present())
app.run()
motion.webp

Copyright(C) sasakima-nao All rights reserved 2002 --- 2024.