PyGTK3: захват строки из клавиатуры - PullRequest
0 голосов
/ 28 декабря 2018

У меня был код, написанный на python3 с использованием GTK3.Программа ждала некоторых вводов с клавиатуры.Например, если я нажал 'q', программа напечатала определенный символ и т. Д. Этот код выглядит как

 keyname = Gdk.keyval_name(event.keyval)
 if keyname == 'q':
        self.textbuffer.insert_at_cursor('you've pressed q')

Я хочу выполнить функцию обратного вызова, когда программа захватывает определенную строку, например, когда янажмите, скажем, «q» и «w» параллельно (я нажимаю «w», не оставляя клавишу «q»), затем программа выполняет определенную функцию.В GTK3 я не нашел ничего, кроме метода Gdk.utf8_to_string_target (event.string), но мне не удалось правильно его использовать.Для нажатия двух символов, таких как ctrl и 'h', легко использовать что-то вроде

ctrl = (event.state & Gdk.ModifierType.CONTROL_MASK)
if ctrl and event.keyval == Gdk.KEY_h:
        self.textbuffer.insert_at_cursor('\n') 

. Я проверил, казалось бы, похожий вопрос Обнаружение определенных нажатий клавиш в GUI , но спрашивал о проверке, еслиспециальная клавиша нажата.Что не в моем случае.В качестве минимального кода мы приводим следующее.

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

class MyWindow(Gtk.Window):
    def __init__(self):

        Gtk.Window.__init__(self, title="awesome gui")
        self.set_resizable(True)
        self.set_default_size(700,550)
        self.grid = Gtk.Grid()
        self.add(self.grid)                        
        self.create_textview()
        self.create_buttons()

    def create_textview(self):

        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_hexpand(True)
        scrolledwindow.set_vexpand(True)
        self.grid.attach(scrolledwindow, 0, 1, 50, 1)
        self.textview = Gtk.TextView()
        scrolledwindow.add(self.textview)
        self.textbuffer = self.textview.get_buffer()
        self.textview.set_editable(False)
        self.textview.set_cursor_visible(False)

    def create_buttons(self):
        self.button1 = Gtk.Button(label="Clear text")   
        self.button1.connect("clicked", self.on_button1_clicked)
        self.grid.attach(self.button1, 0,  0, 1, 1)      
        self.button2 = Gtk.Button(label="Start capturing")
        self.button2.connect("key-release-event", self.on_key_release) 
        self.grid.attach_next_to(self.button2,self.button1,\
        Gtk.PositionType.RIGHT, 1, 1)  

    def on_button1_clicked(self, widget):
        self.textbuffer.set_text('')

    def on_key_release(self, widget, event, data=None):
        keyval = event.keyval       
        keyname = Gdk.keyval_name(keyval)
        ctrl = (event.state & Gdk.ModifierType.CONTROL_MASK)

        if keyval == Gdk.KEY_space: 
            self.textbuffer.insert_at_cursor(' ') #space

        if keyname == 'q':
            self.textbuffer.insert_at_cursor('you pressed q')

       # etc..

        if ctrl and keyval == Gdk.KEY_h:
            self.textbuffer.insert_at_cursor('\n') #change line when ctrl + h is pressed

win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()

Мой вопрос: могу ли я иметь что-то вроде

#you press q and after w or w and after q or the same time you press q and w
if keyname == 'qw': 
    self.textbuffer.insert_at_cursor('you pressed qw')

Есть идеи?Пожалуйста, если возможно, предоставьте код, подтверждающий вашу точку зрения!

Ответы [ 2 ]

0 голосов
/ 02 января 2019

Ускоритель может быть более удачным решением, но отслеживание нажатых и отпущенных клавиш может быть ближе к тому, что вам нужно.

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

class MyWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="awesome gui")
        self.set_resizable(True)
        self.set_default_size(700,550)
        self.grid = Gtk.Grid()
        self.add(self.grid)                        
        self.create_textview()
        self.create_buttons()
        self.buffer = []

    def create_textview(self):
        scrolledwindow = Gtk.ScrolledWindow()
        scrolledwindow.set_hexpand(True)
        scrolledwindow.set_vexpand(True)
        self.grid.attach(scrolledwindow, 0, 1, 50, 1)
        self.textview = Gtk.TextView()
        scrolledwindow.add(self.textview)
        self.textbuffer = self.textview.get_buffer()
        self.textview.set_editable(False)
        self.textview.set_cursor_visible(False)

    def create_buttons(self):
        self.button1 = Gtk.Button(label="Clear text")   
        self.button1.connect("clicked", self.on_button1_clicked)
        self.grid.attach(self.button1, 0,  0, 1, 1)      
        self.button2 = Gtk.Button(label="Start capturing")
        self.button2.connect("key-release-event", self.on_key_release)
        self.button2.connect("key-press-event", self.on_key_down)
        self.grid.attach_next_to(self.button2,self.button1,\
        Gtk.PositionType.RIGHT, 1, 1)  

    def on_button1_clicked(self, widget):
        self.textbuffer.set_text('')

    def on_key_release(self, widget, event, data=None):
        keyval = event.keyval       
        keyname = Gdk.keyval_name(keyval)
        ctrl = (event.state & Gdk.ModifierType.CONTROL_MASK)
        if keyname in self.buffer:
            self.buffer.remove(keyname)
            if self.buffer:
                self.textbuffer.insert_at_cursor('you released '+'+'.join(self.buffer)+'\n')

    def on_key_down(self, widget, event, data=None):
        keyval = event.keyval       
        keyname = Gdk.keyval_name(keyval)
        if keyname in 'wqs' and keyname not in self.buffer:
            self.buffer.append(keyname)
            if self.buffer:
                self.textbuffer.insert_at_cursor('you pressed '+'+'.join(self.buffer)+'\n')

win = MyWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
0 голосов
/ 28 декабря 2018

есть функция (в gtk), которая похожа на ваши потребности.

https://developer.gnome.org/gtk3/stable/gtk3-Keyboard-Accelerators.html#gtk-accel-group-connect

она соединяет ключ и ключ-мод (https://github.com/bstpierre/gtk-examples/blob/master/c/accel.c)

если вы действительно хотите захватить строку, то вы можете попробовать воссоздать функцию, указанную в gtk_accel_group

, источник которой можно найти в git (это код c-source https://github.com/GNOME/gtk/blob/master/gtk/gtkaccelgroup.c)

...