使用异步方式在运行时显示 GTK Spinners

在一个 Gtk 应用程序中,希望在运行函数期间显示一个 Gtk 的 Spinner 控件,但是在函数运行期间,Spinner 控件不会出现,而是窗口变暗,就像窗口没有响应一样。

2、解决方案
出现这种情况是因为主循环被正在运行的函数锁住了。一种解决方案是通过异步的方式调用函数,一种方式是使用Python的线程,另一种方式是使用 Gtk 的 idle_add 方法,该方法会在主循环的空闲时间调用函数。

下面是使用Python的线程实现异步函数调用的代码示例:

import threading

class Thread(threading.Thread):
    def __init__(self,callback,*args,**kwargs):
        self.__callback = callback
        threading.Thread.__init__(self,*args,**kwargs)
    def run(self):
        try:
            if self.__target:
                print('thread')
                _self = self.__kwargs.get('self',self.__args[0])
                self.__callback(_self, self.__target(*self.__args, **self.__kwargs))
        finally:
            # Avoid a refcycle if the thread is running a function with
            # an argument that has a member that points to the thread.
            del self.__target, self.__args, self.__kwargs        

def background(callback):
    print('background')
    def wrapper(fun):
        print('wrapper')
        def inner(*args,**kwargs):
            print('inner')
            Thread(callback=callback,target=fun,args=args,kwargs=kwargs).start()
        return inner
    return wrapper

def spinner(fun):
    def inner(self,*args,**kwargs):
        self.show()
        result = fun(self,*args,**kwargs)
        self.hide()
        return result
    return inner


def spinner_hide(fun):
    def inner(self,*args,**kwargs):
        result = fun(self,*args,**kwargs)
        self.hide()
        return result
    return inner

def spinner_show(fun):
    def inner(self,*args,**kwargs):
        self.show()
        result = fun(self,*args,**kwargs)
        return result
    return inner


class A(object):
    @spinner_hide
    def my_function_callback(self,data):
        print('callback')
        print(data)
    @spinner_show
    @background(my_function_callback)
    def my_function(self, input):
        # do something here that takes long time
        print(input)
        output=input
        return output

    def show(self): print('showed')
    def hide(self): print('hidden')

a=A()
a.my_function('gogo')

当调用 a.my_function('gogo') 时,my_function 函数会被异步地执行,在函数执行期间,spinner 会显示,函数执行完成后,spinner 会隐藏。

另一种方式是使用 Gtk 的 idle_add 方法,代码示例如下:

import gobject

def async(func):
    """Make a function mainloop friendly. the function will be called at the
    next mainloop idle state."""
    def new_function(*args, **kwargs):
        def async_function():
            func(*args, **kwargs)
            return False
        gobject.idle_add(async_function)
    return new_function

class A(object):
    def __init__(self):
        self.spinner = gtk.Spinner()
        self.spinner.hide()

    @async
    def my_function(self, input):
        self.spinner.show()
        # do something here that takes long time
        print(input)
        output=input
        self.spinner.hide()
        return output

    def show(self):
        self.spinner.show()

    def hide(self):
        self.spinner.hide()

    def main(self):
        a.my_function('gogo')

if __name__ == "__main__":
    a = A()
    a.main()
    gtk.main()

当调用 a.main() 时,my_function 函数会被异步地执行,在函数执行期间,spinner 会显示,函数执行完成后,spinner 会隐藏。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值