2012-10-17 30 views
1

我正在編寫一個需要用戶登錄的UI。登錄本身可能需要長達10秒。登錄後,會對一個下載和填充TreeView的函數進行冗長的調用。我試圖使用glib.timeout_add()來鎖定用戶界面,而登錄和populatelist()函數被調用,但gtk.main()仍然鎖定它。Python:使用glib.timeout_add運行帶有鎖定UI的異步函數

def connect(self, widget, data): 
    self.debug("Logging in") 
    glib.timeout_add(500, self.login) 
    self.debug("Logged in") 

def login(self): 
    self.debug("Starting self.gm.doLogin") 
    logged_in = self.gm.doLogin(self.email, self.password) 
    self.debug("Finsished self.gm.doLogin") 
    if self.gm.logged_in: 
     if self.connect_button.get_label() == "Connecting": 
      self.debug("Getting SongWin") 
      glib.timeout_add(500, self.populateSongWin) 
      self.debug("Getting playLists") 
      glib.timeout_add(500, self.populatePlaylists) 
      self.action = "Getting songs" 
      self.status_label.set_label("Status: %s; Songs: %s; Playlists: %s" %\ 
             (self.gm.logged_in, 
             len(self.gm.library), 
             len(self.gm.playlists))) 
      self.connect_button.set_label("Disconnect") 
      self.connect_button.set_sensitive(True) 
    self.action = "None" 
    return False 

我知道這以某種方式工作,因爲我可以看到:

DEBUG: Logging in 
DEBUG: Logged in 
DEBUG: Starting self.gm.doLogin 

任何人能告訴我什麼,我做錯了什麼?本質上,應用程序需要在這個順序運行:

  1. self.gm.doLogin()
  2. self.populateSongWin()
  3. self.populatePlaylists()

這三種方法都耗時,需要按順序運行,而不是阻止用戶界面。

+0

在後臺線程中運行登錄/冗長呼叫,[示例](http://askubuntu.com/a/183315/3712) – jfs

回答

3

看起來應用程序被阻止,但它正在處理事件。其中一個事件必須終止循環。您可以查看event loops in Wikipedia背後的想法。儘管如此,在你的代碼中,你使用的是局部變量來獲取登錄狀態,但是你正在使用一個實例變量來驗證狀態。

def login(self): 
    self.debug("Starting self.gm.doLogin") 
    logged_in = self.gm.doLogin(self.email, self.password) 
    self.debug("Finsished self.gm.doLogin") 
    if self.gm.logged_in:         <= 
     [...] 

相反的self.gm.logged_in應該在條件中使用logged_inif聲明。