2013-08-24 1 views
1

내 기능이 실행되는 동안에 만 Gtk 회 전자 위젯을 표시하고 싶습니다. 예를 들어 :기능 실행 중 Gtk Spinner 표시

[...] 

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는 윈도우가 응답하지 않는 창으로 어두워 그 ​​위에 실행되는 동안 회가 나타나지 않습니다. 회 전자를 사용하고 응답하지 않는 창을 방지하려면 어떻게해야합니까? 감사합니다

답변

1

메인 루프가 잠겨 있기 때문에 창이 어두워집니다 my_function.

비동기 메서드를 호출 해보십시오. gobject 또는 gdk 스레드로 구현 될 수 있습니다. 파이썬 스레드를 사용한이 예제.

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

>>>이 배경 인 출력 후, 메인 쓰레드가 유휴 상태가 있다는 것을 의미 IDLE

샘플을 실행

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

결과 :

많은 프린트 함수의 순서를 설명한다.

+0

@eri 많이 장식에 전달 당신의 대답을 위해! 파이썬에 대해서는 경험이별로 없습니다. 내 코드에 대한 답변에 코드를 추가했지만 작동하지 않는 것 같습니다. (어쩌면 내가 뭔가 잘못하고있는 것 같습니다.)이 코드는 다음과 같습니다. https://dl.dropboxusercontent.com/u/76369534/Threading 나는 rotate_button을 클릭하면 회전 – mnrl

+0

을 표시하고 이미지 나던 회 전자 나던 rotate_button 코드를 눌러 실행' 내부 스레드 을 보였다'터미널에 나타납니다 그리고 메인 창을 닫으면'은 Gtk-CRITICAL ** : gtk_label_set_text : 주장'GTK_IS_LABEL (레이블) ' 숨겨진 없음 이'에 터미널. 나타납니다 콜백 실패 주셔서 감사합니다. 귀하의 돌이 @mnrl – mnrl

+0

는 gobject.mainloop''입니까? 그것은 마법이 필요합니다.'gobject.threads_init()'돌이 = gobject.MainLoop'전()' – eri

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):...