Bagaimana cara saya membuat dan menggunakan pintasan keyboard di aplikasi Gtk yang saya kembangkan?

9

Saya membuat aplikasi untuk Showdown Aplikasi Ubuntu dengan Python + Gtk dengan cepat. Saya menyebutnya Discvur. Saya ingin memasukkan beberapa pintasan keyboard.

Mencari di web, saya menemukan halaman ini tentang AccelGroup dan halaman ini tentang gtk_widget_add_accelerator tapi saya tidak mengerti bagaimana memulainya. Bisakah Anda memberi tahu saya bagaimana saya akan menentukan sinyal yang sesuai dan kemudian menggunakannya dalam aplikasi saya?

Agmenor
sumber
Tautan pertama rusak ...
WinEunuuchs2Unix

Jawaban:

8

Berikut adalah beberapa bit kode dari salah satu aplikasi Python + Gtk saya, lebih lanjut diperpanjang sesuai dengan komentar untuk jawaban ini:

self.my_accelerators = Gtk.AccelGroup()
self.entry = Gtk.builder.get_object("entry1")
self.add_accelerator(self.entry, "<Control>b", signal="backspace")
...

def add_accelerator(self, widget, accelerator, signal="activate"):
    """Adds a keyboard shortcut"""
    if accelerator is not None:
        #if DEBUG:
            #print accelerator, widget.get_tooltip_text()
        key, mod = Gtk.accelerator_parse(accelerator)
        widget.add_accelerator(signal, self.my_accelerators, key, mod, Gtk.AccelFlags.VISIBLE)
Bryce
sumber
Terima kasih tapi aku punya kesalahan ini: self.add_accelerator(self.quick_add_entry, "<Control>l", signal="grab-focus") AttributeError: 'DiscvurWindow' object has no attribute 'quick_add_entry'. Ketika saya mencoba pencarian web "quick_add_entry", saya tidak dapat menemukannya di mana pun. Apakah Anda yakin itu adalah fungsi yang benar? Di mana saya dapat menemukan lebih banyak informasi / tutorial untuk ini? Selain itu, apakah "<Control> l" berarti Ctrl + l atau apakah ini salah ketik?
Agmenor
Ini bukan fungsi, itu hanya nama widget apa pun yang Anda hubungkan dengan akselerator. Saya telah merevisinya menjadi lebih jelas.
Bryce
Terima kasih atas jawaban Anda. Pertama, saya mengambil kebebasan untuk mengubah "gtk" menjadi "Gtk". Kedua, ketika saya menjalankan kode Anda saya mendapatkan "NameError: nama global 'DEBUG' tidak didefinisikan", jadi saya kira ini adalah variabel dari skrip Anda sendiri. Jadi saya berkomentar dalam naskah saya sendiri. Ketiga, setelah berkomentar, saya mendapatkan kesalahan "AttributeError: objek 'DiscvurWindow' tidak memiliki atribut 'akselerator'". Saya minta maaf jika ini seharusnya terbukti tetapi dokumentasinya masih tidak jelas bagi saya; khususnya dokumentasi mengatakan add_accelerator membutuhkan 6 argumen?
Agmenor
Benar, Anda perlu membuat akselerator sendiri; Saya telah memperbarui contoh untuk menunjukkan caranya.
Bryce
Setelah sedikit riset dan percobaan gagal, saya bisa mendapatkan skrip yang berfungsi. Bisakah Anda memverifikasinya? Jika menurut Anda itu benar, saya akan (atau Anda dapat) mengubah jawaban Anda: paste.ubuntu.com/1053516 . Saya akan sangat menghargai ulasan Anda, Bryce. "Sebuah riset kecil" adalah eufemisme, tetapi saya kira lebih baik mempelajari seorang pria cara memancing daripada memberinya ikan. Jadi terima kasih lagi.
Agmenor
6

Inilah kode yang akhirnya berhasil. Karena sangat tergantung pada lingkungan pengembangan saya Dengan cepat + Glade + Python + Gtk, saya membuatnya menjadi jawaban yang independen. Jawaban Bryce banyak membantu, dan begitu pula pertukaran saya dengan aking1012 .

Kode aktual, dalam editor teks:

# Accelerators
self.my_accelerators = Gtk.AccelGroup()
self.window = self.builder.get_object("discvur_window")
self.window.add_accel_group(self.my_accelerators)
self.entry = self.builder.get_object("entry1")
self.add_accelerator(self.entry, "<Control>b", signal="backspace")



def add_accelerator(self, widget, accelerator, signal="activate"):
    """Adds a keyboard shortcut"""
    if accelerator is not None:
        #if DEBUG:
            #print accelerator, widget.get_tooltip_text()
        key, mod = Gtk.accelerator_parse(accelerator)
        widget.add_accelerator(signal, self.my_accelerators, key, mod, Gtk.AccelFlags.VISIBLE)
        print "The accelerator is well added with the signal " + signal

def on_erasing(self, widget):
    print "It works."

Di Glade, saya membuat GtkEntry bernama "entry1" di jendela saya yang disebut "discvur_window". Pada tab 'Sinyal', saya memberi sinyal "backspace" penangan yang disebut "on_erasing".

Sekarang, menekan Backspaceatau Ctrl+ Bmembuat terminal cetak "Berhasil.".

Agmenor
sumber
Apakah ini dapat digunakan untuk menonaktifkan pintas Ctrl + F4 untuk menutup jendela?
Juzer Ali
Maksudmu Alt + F4? Saya tidak tahu, saya belum mencoba.
Agmenor
Maksud saya Ctrl + F4 dan Alt + F4
Juzer Ali
2

Saya telah mengemas ulang jawaban yang diberikan di utas ini menjadi contoh mandiri:

#!/usr/bin/env python2

import signal

from gi.repository import Gtk

def bind_accelerator(accelerators, widget, accelerator, signal='clicked'):
    key, mod = Gtk.accelerator_parse(accelerator)
    widget.add_accelerator(signal, accelerators, key, mod, Gtk.AccelFlags.VISIBLE)

def on_recompute_base_encryption_key_hash(widget):
    print 'Thinking... (This could take forever)'

def main():

    if 'gtk':
        window = Gtk.Window()
        window.connect("delete-event", Gtk.main_quit)

        if 'accelerator-demo':
            # Accelerators
            accelerators = Gtk.AccelGroup()
            window.add_accel_group(accelerators)

            # Widget
            target_widget = Gtk.Button('Recompute Base Encryption Key Hash')
            target_widget.connect('clicked', on_recompute_base_encryption_key_hash)
            window.add(target_widget)

            # Bind
            bind_accelerator(accelerators, target_widget, '<Control>b')

        window.show_all()
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        Gtk.main()

if __name__ == '__main__':
    main()

Juga tersedia sebagai intisari: https://gist.github.com/thorsummoner/230bed5bbd3380bd5949

Catatan: Sinyal default adalah clicked, bukan activatekarena Aplikasi tidak boleh terhubung ke ::activatesinyal, tetapi gunakan ::clickedsinyal Gtk.Tombol .

ThorSummoner
sumber
Jadi saya perhatikan; saat menggunakan clickedakselerator dapat dihaluskan dengan sangat cepat, tetapi tombol tidak secara visual menekan. Saat menggunakan activate, tombol akan tertekan, tetapi akselerator hanya dapat ditekan setelah tekanan visual selesai.
ThorSummoner