1

Imagine I want to make a simple program with GUI like this.

this is my code:

from gi.repository import Gtk
import gobject

class gui():
    def __init__(self):
        self.window = Gtk.Window()
        self.window.connect('delete-event', Gtk.main_quit)

        self.box = Gtk.Box()
        self.window.add(self.box)

        self.progressbar = Gtk.ProgressBar()
        self.box.pack_start(self.progressbar, True, True, 0)

        self.button = Gtk.Button(label='Start')
        self.button.connect('clicked', self.on_button_clicked)
        self.box.pack_start(self.button, True, True, 0)

        self.window.show_all()
        Gtk.main()

    def on_button_clicked(self, widget):
        self.task = self.iters(100000)
        gobject.idle_add(self.task.next)

    def iters(self, j):
        i = j
        while i > 0 :
            i -= 1
            print i
            self.progressbar.set_fraction((j - float(i)) / j)
            yield True
        yield False

if __name__ == '__main__':
    gui = gui()

I know how to make progressbar work if I put everything in one script like that. But, what if I want to separate gui part from logic part? So, it would be like this:

GUI.py

from gi.repository import Gtk

class gui():
    def __init__(self):
        self.window = Gtk.Window()
        self.window.connect('delete-event', Gtk.main_quit)

        self.box = Gtk.Box()
        self.window.add(self.box)

        self.progressbar = Gtk.ProgressBar()
        self.box.pack_start(self.progressbar, True, True, 0)

        self.button = Gtk.Button(label='Start')
        self.button.connect('clicked', self.on_button_clicked)
        self.box.pack_start(self.button, True, True, 0)

        self.window.show_all()
        Gtk.main()

    def on_button_clicked(self, widget):
        //how to implement it

if __name__ == '__main__':
    gui = gui()

Iteration.py

class Iteration():
def iters(self, j):
    i = j
    while i > 0 :
        i -= 1
        print i

EDIT: One more thing, the first code above works, but why do I get this message:

/usr/lib/python2.7/dist-packages/gobject/constants.py:24: Warning: g_boxed_type_register_static: assertion `g_type_from_name (name) == 0' failed
import gobject._gobject

EDIT: Okay, imagine I have one module like this one: Works.py

def getImageFromInternet(uri):
    #some code to get image from internet

this getImageFromInternet function is not iterable. What I want to do is processing this function in the background while updating the progressbar and doing other thing with gui. Do I need a thread for this?

4

1 回答 1

0

创建一个更新 GUI 并驱动底层数据模型生成器的生成器,并将其传递给idle_add. 例如(未经测试):

    def on_button_clicked(self, widget):
        cnt = 10000
        task = self.iters(cnt)
        def gui_iter():
            for i, ignore in enumerate(task, 1):
                self.progressbar.set_fraction(i / cnt)
                yield True
            yield False
        gobject.idle_add(gui_iter().next)
于 2013-06-03T13:59:06.277 回答