在Python中使用GTK / GIO异步读取

时间:2018-06-11 04:45:52

标签: python python-3.x gtk gtk3 gio

我试图在Python中使用GTK / GIO进行异步读取,但是虽然读取本身工作正常(因为只有在输入了所需的字节数后才调用回调),我还没有#39 ; t能够找到任何方法来实际访问结果。

鉴于此代码:

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')

换句话说......

  • get_user_data()get_task_data()似乎没有任何帮助,因为它们返回整数(其含义我不知道)
  • 来自read_all_finish()的返回值似乎无济于事,因为它只是一个成功/失败bool加上一个bytes_read整数字段
  • 我们给read_all_async()的缓冲区似乎没有任何帮助,因为它保持不变,即使人们可能期望它能保持读取的结果......

我也试过......

  • read_all_finish()调用之前检查相同的内容,以防该调用由于某种原因执行类似清除缓冲的操作 - 没有骰子,这会产生相同的结果
  • 使用array('b', [0]*4)代替bytearray - 同样具有相同的效果
  • 使用整数代替buf(因为似乎旧版本的API以这种方式工作) - 这只会产生TypeError: Must be sequence, not int
  • 使用文件而不是标准输入 - 无需更改
  • 使用read_async() / read_finish()代替 - 无需更改
  • ......可能还有一些我甚至不记得的事情

在这一点上,我真的在我的脑海里结束了 - 我只是在做一些可怕的错误,或者GIO的python绑定在异步方法方面被严重破坏了吗? / p>

1 个答案:

答案 0 :(得分:0)

尽管没有抱怨标准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()