2012-10-02 79 views
0

發送HTTP請求,我有這樣的代碼:爲什麼我不能查看更新的標籤,而在Python

def on_btn_login_clicked(self, widget): 
    email = self.log_email.get_text() 
    passw = self.log_pass.get_text() 
    self.lbl_status.set_text("Connecting ...") 
    params = urllib.urlencode({'@log_email': email, '@log_pass': passw, '@action': 'login', '@module': 'user'}) 
    headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"} 
    conn = httplib.HTTPConnection("website.com") 
    self.lbl_status.set_text("Logging in ...") 
    conn.request("POST", "/ajax.php", params, headers) 
    response = conn.getresponse() 
    print response.status 
    self.lbl_status.set_text("") 
    data = response.read()  
    print data 
    conn.close() 

self.lbl_status不會改變,直到請求完成,所以它不顯示任何因最後的set_text函數。

爲什麼會發生這種情況,以及如何避免/解決這個問題?

+0

你使用的是什麼GUI庫? –

+0

我認爲GTK。我正在快速Ubuntu 12.04 –

+0

什麼是你的腳本的頂部的進口聲明。只是要確保您使用的 –

回答

0

下面是一個簡單的下載器的工作示例,僅供參考。如果您希望圖形用戶界面具有響應性,並且在執行長時間運行或阻止操作時不需要凍結,則需要使用多線程。我把這個例子放在一起,基於this stack overflow question和這篇出色的文章Using threads in PyGTK。 Ubuntu iso的默認網址需要一段時間才能下載,並且應該提供一個很好的演示。當提示它將下載並保存文件到當前目錄時,你可以輸入你想要的任何url。

from threading import Thread 
import time 
import gtk, gobject, urllib 

URL = 'http://releases.ubuntu.com//precise/ubuntu-12.04.1-desktop-i386.iso' 

def download(url): 
    filename = url.split('/')[-1] 
    out = open(filename, 'wb') 
    gobject.idle_add(label.set_text, "connecting...") 
    f = urllib.urlopen(url) 
    buffer = f.read(1024) 
    counter = 0 
    while buffer: 
     counter += len(buffer) 
     out.write(buffer) 
     msg = "downloaded {0:,} bytes".format(counter) 
     gobject.idle_add(label.set_text, msg) 
     buffer = f.read(1024) 
    out.close() 
    gobject.idle_add(label.set_text, "download complete") 

def clicked(button): 
    url = entry.get_text() 
    Thread(target=download, args=(url,)).start() 


gtk.gdk.threads_init() 
win = gtk.Window() 
win.set_default_size(400, 100) 
entry = gtk.Entry() 
entry.set_text(URL) 
label = gtk.Label("Press the button") 
button = gtk.Button(label="Download") 
button.connect('clicked', clicked) 

box = gtk.VBox() 
box.pack_start(entry) 
box.pack_start(label) 
box.pack_start(button) 
win.add(box) 

win.show_all() 

gtk.main() 
0

在主循環運行之前,Gtk不會更新任何東西。這意味着它首先完成所有更改,並在完成所有更改後才進行更新。這是因爲它打算所有的回調都是原子的(在可以忽略的時間內完成)。回調不應該使用阻塞呼叫,因爲這意味着接口將凍結。

這裏有兩種可能的解決方案。最好的辦法是在響應準備就緒後註冊新的回調函數,然後返回主循環。但是,這可能並不容易。一個骯髒的解決方法是在進行阻塞調用之前強制主循環處理未決事件。它會更新標籤。你可以這樣做

while gtk.events_pending(): 
    gtk.main_iteration (False) 

但正如我寫的,沒有從回調中調用任何阻塞函數是更乾淨。

相關問題