首页 > 解决方案 > 在 Python 中使用 GTK/GIO 异步读取

问题描述

我正在尝试在 Python 中使用 GTK/GIO 进行异步读取,但是虽然读取本身可以正常工作(因为仅在输入所需的字节数后才调用回调),但我无法找到任何实际访问结果的方法。

鉴于此代码:

from gi.repository import Gtk, GLib, Gio
import sys

def callback(stream, task):
        result = stream.read_all_finish(task)
        print(stream, task, task.get_user_data(), task.get_task_data(), result, buf)
        Gtk.main_quit()

buf = bytearray(4)

stream = Gio.UnixInputStream.new(sys.stdin.fileno(), False)
stream.read_all_async(buf, GLib.PRIORITY_DEFAULT, None, callback)

Gtk.main()

运行时,它会等到至少输入了 4 个字节,所以一个a<return>不会导致它退出,但第二个会。打印结果如下:

<Gio.UnixInputStream object at 0x7f1045dc3708 (GUnixInputStream at 0x1b8c160)> <Gio.Task object at 0x7f1045dc3bd0 (GTask at 0x1b8e860)> 28890912 28207104 (True, bytes_read=4) bytearray(b'\x00\x00\x00\x00')

换句话说...

我也试过...

在这一点上,我真的束手无策了——我只是做错了什么,还是 GIO 的 python 绑定在异步方法方面被严重破坏了?

标签: pythonpython-3.xgtkgtk3gio

解决方案


尽管没有抱怨标准 python bytearray/ array,但它实际上不适用于那些;你需要使用GLib.ByteArray它才能工作。

换句话说,这将起作用:

from gi.repository import Gtk, GLib, Gio
import sys

def callback(stream, task):
        result = stream.read_all_finish(task)
        print(buf)
        Gtk.main_quit()

buf = GLib.ByteArray.new_take(bytes(4))

stream = Gio.UnixInputStream.new(sys.stdin.fileno(), False)
stream.read_all_async(buf, GLib.PRIORITY_DEFAULT, None, callback)

Gtk.main()

推荐阅读