0

我有这个代码:

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功能,它不会显示任何内容。

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

4

2 回答 2

0

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

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

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

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

于 2012-10-02T19:55:00.410 回答
0

下面是一个简单下载器的工作示例,仅用于说明目的。如果您希望您的 GUI 在执行一些长时间运行或阻塞操作时响应并且不冻结,则需要使用多线程。我根据这个堆栈溢出问题和这篇优秀的文章Using threads in PyGTK把这个例子放在一起。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()
于 2012-10-02T20:19:14.563 回答