我有一些使用GTK3用python3编写的代码。程序等待键盘的一些输入。例如,如果我按“ q”,程序将打印一个特定的符号,等等。 这段代码看起来像
keyname = Gdk.keyval_name(event.keyval)
if keyname == 'q':
self.textbuffer.insert_at_cursor('you've pressed q')
当程序捕获特定字符串时,我想执行一个回调函数。当我同时按下“ q”和“ w”(我按下“ w”而不离开键“ q”)时,程序将执行特定功能。 除了一个名为Gdk.utf8_to_string_target(event.string)的方法,我没有在GTK3中找到任何东西,但我没有正确使用它。要按下两个字符(例如ctrl和'h'),可以使用类似的
ctrl = (event.state & Gdk.ModifierType.CONTROL_MASK)
if ctrl and event.keyval == Gdk.KEY_h:
self.textbuffer.insert_at_cursor('\n')
我检查了一个看似相似的问题Detect specific keypresses in 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')
有什么想法吗?请,如果有可能,请提供一些代码来证明您的观点!
答案 0 :(得分:1)
有一个函数(在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源代码https://github.com/GNOME/gtk/blob/master/gtk/gtkaccelgroup.c)
答案 1 :(得分:1)
您必须创建您的个人“缓冲区”,该缓冲区将“缓冲”按键并在每个步进按键中检查这些按键是否符合所需条件。如果条件不符合,请记住清空缓冲区...
还请注意,您的代码不会返回unicode字符。因此,准备放松一些听众...
要获取Unicode字符,必须使用chr(Gdk.keyval_to_unicode(event.keyval))
。
答案 2 :(得分:0)
Accelerator可能是更好的解决方案,但跟踪按键的按下和释放可能更接近您的需求。
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()