为什么可以';在Python中发出HTTP请求时查看对标签的更新

为什么可以';在Python中发出HTTP请求时查看对标签的更新,python,httplib,Python,Httplib,我有以下代码: 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

我有以下代码:

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\u状态
才会更改,因此由于上次的
set\u text
功能,它不会显示任何内容


为什么会发生这种情况,以及如何避免/修复这种情况?

Gtk在主循环运行之前不会更新任何内容。这意味着它首先进行所有更改,只有在完成所有更改后才进行更新。这是因为它希望所有回调都是原子的(在可忽略不计的时间内完成)。回调永远不应该使用阻塞调用,因为这意味着接口将冻结

这里有两种可能的解决方案。最好的方法是在响应就绪时注册一个新的回调,然后返回到主循环。然而,这可能并不容易。一个棘手的解决方法是在进行阻塞调用之前,强制主循环处理挂起的事件。然后它将更新标签。你可以用它来做这个

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

但正如我所写的,不从回调调用任何阻塞函数要干净得多。

下面是一个简单下载程序的工作示例,仅供说明。如果您希望GUI在执行长时间运行或阻塞操作时能够响应并且不冻结,则需要使用多线程。我根据这篇优秀的文章把这个例子放在一起。Ubuntu iso的默认url需要一段时间才能下载,并且应该提供一个很好的演示。当系统提示您下载文件并将其保存在当前目录中时,您可以输入所需的任何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()

你在用什么图形用户界面库?我想是GTK。我在ubuntu 12.04上,脚本顶部有哪些导入语句。为了确保您正在使用的GUI库,这里有:import gettext import httplib,urllib from gettext import gettext as u gettext.textdomain('noc-client')from gi.repository import Gtk 35; pylint:disable=E0611 import logging logging logger=logging.getLogger('noc#client'))从noc_client_lib导入窗口从noc_client.AboutNocClientDialog导入从noc_client.PreferencesNocClientDialog导入PreferencesNocClientDialog是否可能因为它完成整个过程太快而看不到更新?