仅在运行功能时显示Gtk Spinner

时间:2013-08-24 09:53:23

标签: python pygtk python-multithreading

我想在我的函数运行时才显示Gtk微调器小部件。例如:

[...]

self.spinner.hide() # hide spinner at startup

self.my_function(input) # run function

def my_function(self, input)
    self.spinner.show() # show spinner when function running
    # do something here that takes long time
    self.spinner.hide() # hide spinner when the process is complete
    return output

我正在使用它,但是在my_function运行时没有出现微调器,在它上面,窗口变暗是一个无响应的窗口。 我应该如何使用微调器并防止窗口无响应? 感谢

2 个答案:

答案 0 :(得分:1)

由于主循环被my_function锁定,窗口变暗。

尝试异步调用您的方法。它可以用gobject或gdk线程实现。这个例子有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')

使用IDLE运行样本的结果

background
wrapper
showed
inner
thread
>>> 
gogo
callback
gogo
hidden

>>>表示主线程变为IDLE,在后台输出后输出。

答案 1 :(得分:1)

如果mainloop是gobject.MainLoop()是使用gobject线程的更好方法。 如果Qt - 使用Qt。

这个装饰器使用gobject.idle_add来使函数异步。但是没有回调

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

在您的函数中实现调用回调而不是return或将其传递给装饰器,如def background(callback):...