PyGTK, Threads и WebKit - PullRequest
       16

PyGTK, Threads и WebKit

2 голосов
/ 25 декабря 2011

В моем приложении PyGTK при нажатии кнопки мне нужно:

  1. Получить html (может занять некоторое время)
  2. Показать в новом окне

При получении html я хочу, чтобы графический интерфейс реагировал, поэтому я решил сделать это в отдельном потоке.Я использую WebKit для рендеринга HTML.

Проблема в том, что я получаю пустую страницу в WebView, когда она находится в отдельном потоке.

Это работает:

import gtk
import webkit

webView = webkit.WebView()
webView.load_html_string('<h1>Hello Mars</h1>', 'file:///')
window = gtk.Window()
window.add(webView)
window.show_all()
gtk.mainloop()

Это не работает, создает пустое окно:

import gtk
import webkit
import threading

def show_html():
    webView = webkit.WebView()
    webView.load_html_string('<h1>Hello Mars</h1>', 'file:///')
    window = gtk.Window()
    window.add(webView)
    window.show_all()

thread = threading.Thread(target=show_html)
thread.setDaemon(True)
thread.start()
gtk.mainloop()

Это потому, что webkit не является поточно-ориентированным .Есть ли обходной путь для этого?

Ответы [ 2 ]

3 голосов
/ 26 декабря 2011

Согласно моему опыту, одна из вещей, которые иногда не работают так, как вы ожидаете с помощью gtk, - это обновление виджетов в отдельных потоках.

Чтобы обойти эту проблему, вы можете работать с данными ви используйте glib.idle_add, чтобы запланировать обновление виджета в главном потоке после обработки данных.

Следующий код представляет собой обновленную версию вашего примера, которая работает дляme (time.sleep используется для имитации задержки получения html в реальном сценарии):

import gtk, glib
import webkit
import threading
import time

# Use threads                                       
gtk.gdk.threads_init()

class App(object):
    def __init__(self):
        window = gtk.Window()
        webView = webkit.WebView()
        window.add(webView)
        window.show_all()

        self.window = window
        self.webView = webView

    def run(self):
        gtk.main()

    def show_html(self):
        # Get your html string                     
        time.sleep(3)
        html_str = '<h1>Hello Mars</h1>'

        # Update widget in main thread             
        glib.idle_add(self.webView.load_html_string,
                      html_str, 'file:///')

app = App()

thread = threading.Thread(target=app.show_html)
thread.start()

app.run()
gtk.main()
0 голосов
/ 26 декабря 2011

Я ничего не знаю о внутренней работе WebKit, но, возможно, вы можете попробовать это с несколькими процессами.

...