PyGTK有线程,gobject,从另一个线程发送信号?

时间:2014-02-24 12:02:28

标签: python multithreading webkit pygtk

我是Python的新手,我想使用pywebkitgtk打开一个网页(这里是google.com) 然后用另一个线程倒计时,
当时间到了,向webview发送信号,下载html作为文件

有没有办法在后台线程中打开gtk.main和倒计时的网页,然后向GUI发送信号,让GUI做点什么..

参考资料:

  1. Downloading a page’s content with python and WebKit
  2. using a separate thread to run code, two approaches for threads in PyGTK.
  3. 这是我的代码,它无法运行,我想我不理解Python的Class ...

    #!/usr/bin/env python
    import sys, threading
    import gtk, webkit
    import time
    import gobject
    
    gobject.threads_init()
    google = "http://www.google.com"
    
    class WebView(webkit.WebView):
        #return page's content
        def get_html(self):
            self.execute_script('oldtitle=document.title;document.title=document.documentElement.innerHTML;')
        html = self.get_main_frame().get_title()
        self.execute_script('document.title=oldtitle;')
        return html
    
    #wait 5 senconds and send a signal
    class TimeSender(gobject.GObject, threading.Thread):
        def __init__(self):
            self.__gobject_init__()
            threading.Thread.__init__(self)
    
        def run(self):
            print "sleep 5 seconds"
            time.sleep(5)
            self.emit("Sender_signal")
    
    gobject.type_register(TimeSender)
    gobject.signal_new("Sender_signal", TimeSender, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ())
    
    #PywebkitGTK, open google.com, receive signal
    class Window(gtk.Window, gobject.GObject):
        def __init__(self, time_sender, url):
            self.__gobject_init__()
            gtk.Window.__init__(self)
            time_sender.connect('Sender_signal', self._finished_loading)
            self._url = url
    
        def open_page(self):
            view = WebView()
            view.get_html()
            view.open(self._url)
            self.add(view)
            gtk.main()
        #write html to file
        def _finished_loading(self, view):
            with open("pagehtml.html", 'w') as f:
                f.write(view.get_html())
            gtk.main_quit()
    
    '''
    def user_callback(object):
        with open("pagehtml2.html", 'w') as f:
            f.write(view.get_html())
        gtk.main_quit()
    '''
    
    if __name__ == '__main__':
        time_sender = TimeSender()
        window = Window(time_sender, google)
        #time_sender.connect("Sender_signal", user_callback)
        time_sender.start()
        window.open_page()
    

    我收到了一个错误:
    AttributeError: 'TimeSender' object has no attribute 'get_html'
    我已经困惑了几天......谢谢

1 个答案:

答案 0 :(得分:0)

看起来你对于信号/对象和线程感到困惑。 _finished_loading方法不会将视图作为参数获取,因为yo没有传递它。如果你把它全局化它应该工作。下面的代码按预期工作。

#!/usr/bin/env python
import sys, threading
import gtk, webkit
import time
import gobject

gobject.threads_init()
google = "http://www.google.com"

class WebView(webkit.WebView):
    #return page's content
    def get_html(self):
        self.execute_script('oldtitle=document.title;document.title=document.documentElement.innerHTML;')
        html = self.get_main_frame().get_title()
        self.execute_script('document.title=oldtitle;')
        return html

#wait 5 senconds and send a signal
class TimeSender(gobject.GObject, threading.Thread):
    def __init__(self):
        self.__gobject_init__()
        threading.Thread.__init__(self)

    def myEmit(self):
        window.emit("Sender_signal")

    def run(self):
        print "sleep 5 seconds"
        time.sleep(5)
        gobject.idle_add(self.myEmit)


gobject.type_register(TimeSender)

#PywebkitGTK, open google.com, receive signal
class Window(gtk.Window, gobject.GObject):
    def __init__(self, time_sender, url):
        self.__gobject_init__()
        gtk.Window.__init__(self)
        self.connect('Sender_signal', self._finished_loading)
        self._url = url

    def open_page(self):
        self.view = WebView()
        self.view.get_html()
        self.view.open(self._url)
        self.add(self.view)
        gtk.main()
    #write html to file
    def _finished_loading(self, view1):
        with open("pagehtml.html", 'w') as f:
            f.write(self.view.get_html())
        gtk.main_quit()

'''
def user_callback(object):
    with open("pagehtml2.html", 'w') as f:
        f.write(view.get_html())
    gtk.main_quit()
'''

if __name__ == '__main__':
    gobject.signal_new("Sender_signal", Window, gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ())
    time_sender = TimeSender()
    window = Window(time_sender, google)
    #time_sender.connect("Sender_signal", user_callback)
    time_sender.start()
    window.open_page()