首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将PyGObject中的线程与python3中的GTK3配合使用

将PyGObject中的线程与python3中的GTK3配合使用
EN

Stack Overflow用户
提问于 2016-03-18 03:22:08
回答 1查看 960关注 0票数 1

因此,我尝试使用线程在基于Python3的应用程序中实现阻塞操作。

#!/usr/bin/env python3

import gi, os, threading, Skype4Py
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib, GObject

skype = Skype4Py.Skype()

def ConnectSkype():
    skype.Attach()

class Contacts_Listbox_Row(Gtk.ListBoxRow):

    def __init__(self, name):
        # super is not a good idea, needs replacement.
        super(Gtk.ListBoxRow, self).__init__()
        self.names = name
        self.add(Gtk.Label(label=name))

class MainInterfaceWindow(Gtk.Window):
    """The Main User UI"""

    def __init__(self):
        Gtk.Window.__init__(self, title="Python-GTK-Frontend")

        # Set up Grid object
        main_grid = Gtk.Grid()
        self.add(main_grid)

        # Create a listbox which will contain selectable contacts
        contacts_listbox = Gtk.ListBox()
        for handle, name in self.GetContactTuples():
            GLib.idle_add(contacts_listbox.add, Contacts_Listbox_Row(name))
        GLib.idle_add(main_grid.add, contacts_listbox)


        # Test label for debug
        label = Gtk.Label()
        label.set_text("Test")
        GLib.idle_add(main_grid.attach_next_to, label, contacts_listbox, Gtk.PositionType.TOP, 2, 1)

    def GetContactTuples(self):
        """
        Returns a list of tuples in the form: (username, display name).
        Return -1 if failure.
        """
        print([(user.Handle, user.FullName) for user in skype.Friends]) # debug
        return [(user.Handle, user.FullName) for user in skype.Friends]

if __name__ == '__main__':

        threads = []

        thread = threading.Thread(target=ConnectSkype) # potentially blocking operation
        thread.start()
        threads.append(thread)

        main_window = MainInterfaceWindow()
        main_window.connect("delete-event", Gtk.main_quit)
        main_window.show_all()
        print('Calling Gtk.main')
        Gtk.main()

基本思想是这个简单的程序应该从Skype API获取一个联系人列表,并构建一个元组列表。GetContactTuples函数设计成功,我发出的打印调用验证了这一点。但是,程序会无限期地挂起,并且永远不会呈现界面。有时,它会产生涉及线程和/或资源可用性的随机错误。一旦这样的错误被

(example.py:31248): Gdk-WARNING **: example.py: Fatal IO error 11 (Resource temporarily unavailable) on X server :1.

我知道这与线程的使用有关,但根据文档here,在接口更新之前添加GLib.idle_add调用似乎就足够了。因此,问题是,为什么这不起作用,以及我如何更正上面的示例?

更新:如果将GLib.idle_add放在与GTK交互的每一行前面,我会得到一个不同的错误。[xcb] Unknown request in queue while dequeuing [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called [xcb] Aborting, sorry about that. python: xcb_io.c:179: dequeue_pending_request: Assertion '!xcb_xlib_unknown_req_in_deq' failed. Aborted (core dumped)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-30 07:02:05

根据您的库版本(在Gobject 3.10.2中不再需要),您实际上可能需要使用GObject.threads_init()显式初始化线程,如下所示:

if __name__ == '__main__':

    threads = []

    thread = threading.Thread(target=ConnectSkype) # potentially blocking operation
    thread.start()
    threads.append(thread)

    main_window = MainInterfaceWindow()
    main_window.connect("delete-event", Gtk.main_quit)

    GObject.threads_init()

    main_window.show_all()
    print('Calling Gtk.main')
    Gtk.main()
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36069835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档