【发布时间】:2018-02-06 15:51:22
【问题描述】:
我正在尝试创建一个测试应用程序。应用程序应在目录中列出图像,在屏幕上显示第一个图像,获取键盘响应并显示第二个图像,获取响应,并对每个图像执行此操作。
我创建了一个 glade 文件,并使用它在 RavensAPM 类中创建接口。林间空地文件中有一个Gtk.Window,其中包含一个Gtk.Box,而后者又包含一个Gtk.Image。我使用run_ravens_apm() 函数列出图像并将图像一张一张地提供给RavensAPM 类。在RavensAPM 类中,我更新图像并使用show_all() 呈现所有内容。
此时我希望应用程序等待来自键 [1-8] 和键盘键 [1-8] 的按键事件。
我检查了GLib.timeout_add() 函数的用法,但我无法从中获得所需的行为。目前,run_ravens_apm() 中的for 循环同时调用RavensAPM 并创建与图像数量一样多的窗口,而无需等待键盘信号/事件。
我尝试将GLib.timeout_add() 放在类的__call__() 方法中,并将类的实例用作函数,但它也不起作用。
我做错了什么?
class RavensAPM:
def __init__(self, test_image):
self.builder = Gtk.Builder()
self.builder.add_from_file('glade/window_ravens_apm.glade')
self.window = self.builder.get_object('window_ravens_apm')
self.window.fullscreen()
self.window.connect('key-release-event', self.on_event_after)
window_height = 1080
self.pixbuf_file = \
GdkPixbuf.Pixbuf.new_from_file_at_scale(test_image,
-1,
window_height,
True)
self.image = self.builder.get_object('ravens_apm_image')
self.image.set_from_pixbuf(self.pixbuf_file)
self.window.show_all()
def on_event_after(self, widget, event):
keys = [i for i in range(49, 57)] + [i for i in range(65457, 65465)]
key_value = event.keyval
if keys in key_value:
self.window.destroy()
return False
def __call__(self):
self.on_event_after()
return True
def run_ravens_apm():
# List the contents of img/ravens_apm
# Use a loop to run RavensAPM for the length of images
interval_ms = 200
img_directory = 'img/ravens_apm'
img_files = os.listdir(img_directory)
img_files.sort()
img_files = img_files[:2]
nr_images = len(img_files)
for i in range(nr_images):
img_file = os.path.join(img_directory, img_files[i])
ravens = RavensAPM(img_file)
GLib.timeout_add(interval_ms, ravens)
print('GLib.timeout_add must wait for Gdk.EventKey event')
print(datetime.datetime.now())
glade 文件的内容如下。
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkWindow" id="window_ravens_apm">
<property name="can_focus">False</property>
<signal name="key-press-event" handler="on_windows_ravens_apm_key_press_event" swapped="no"/>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkImage" id="ravens_apm_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-missing-image</property>
<signal name="key-press-event" handler="on_ravens_apm_keypress" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
【问题讨论】:
-
最重要的是,我要说的是您来自 Gtk 和 Python 以外的编程语言。请查看python-gtk-3-tutorial.readthedocs.io/en/latest/builder.html 以开始使用。
-
这不是
timeout_add所做的。阅读 GLib 的主事件循环,您的按键事件处理程序基本上应该在您收到按键时交换图像。 -
谢谢@nemequ。读完你的评论后,我意识到我必须做些什么。通过使用一个简单的回调方法,我创建了我想要的脚本。
标签: python-3.x gtk3 glib