wxpython кажется мертвым при работе с событиями без остановки
Я пишу веб-сканер, используя wxpython для отображения результатов в реальном времени. Предполагая, что есть только одна кнопка с именем crawl
на окне. когда я нажал кнопку, появится новое диалоговое окно, и TextCtrl в новом диалоговом окне отобразит текущий URL, который сканируется.
Коды могут быть упрощены следующим образом (просто пользовательский интерфейс с WebCrawler
нить на OnDisplayClick
функция):
# -*- coding: utf-8 -*-
import wx
class Main ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer3 = wx.BoxSizer( wx.VERTICAL )
self.Crawl = wx.Button( self, wx.ID_ANY, u"Crawl", wx.DefaultPosition, wx.DefaultSize, 0 )
self.Crawl.SetDefault()
bSizer3.Add( self.Crawl, 0, wx.ALL, 5 )
self.SetSizer( bSizer3 )
self.Layout()
self.Centre( wx.BOTH )
# Connect Events
self.Crawl.Bind( wx.EVT_BUTTON, self.OnDisplayClick )
def __del__( self ):
pass
# Virtual event handlers, overide them in your derived class
def OnDisplayClick( self, event ):
#Show the display window
newDisplay = Display(self)
newDisplay.show()
############################################################
## start a multi-threading webcrawler ##
############################################################
web_crawler = WebCrawler(newDisplay.current_url)
web_crawler.startCrawl()
class Display ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHintsSz( wx.DefaultSize, wx.DefaultSize )
bSizer4 = wx.BoxSizer( wx.VERTICAL )
self.cur_url = wx.StaticText( self, wx.ID_ANY, u"Current_URL: ", wx.DefaultPosition, wx.DefaultSize, 0 )
self.cur_url.Wrap( -1 )
bSizer4.Add( self.cur_url, 0, wx.ALL, 5 )
self.current_url = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
bSizer4.Add( self.current_url, 0, wx.ALL, 5 )
self.SetSizer( bSizer4 )
self.Layout()
self.Centre( wx.BOTH )
def __del__( self ):
pass
UI:
WebCrawler является многопоточным сканером, я передаю TextCtrl (current_url
) в WebCrawler, чтобы позволить ему отображать текущий URL для сканирования в окне дисплея, но когда я нажимаю на кнопку сканирования, интерфейс кажется мертвым, я полагаю, это потому, что многопоточный WebCrawler работает и поток пользовательского интерфейса не может получить Возможность отображения нового окна. я попытался написать еще два потока, используя потоки. Таким образом, один используется для отображения нового окна, другой для WebCrawler, но мне это не удалось, приложение часто закрывалось сразу, хотя оно может отображать окно и выполнять потоковые операции сканирования в течение нескольких секунд. и иногда он говорил мне что-то вроде:
(python2.7:5231): Pango-CRITICAL **: pango_layout_get_iter: assertion `PANGO_IS_LAYOUT (layout)' failed
(python2.7:5404): GLib-GObject-CRITICAL **: g_object_ref: assertion `object->ref_count > 0' failed
эти две роли следующие:
class UpdateThread(threading.Thread):
""" WebCrawler thread """
def __init__(self, webCrawl):
threading.Thread.__init__(self)
self.webCrawl = webCrawl
def run(self):
self.webCrawl.start()
class CrawlShowThread(threading.Thread):
""" Display thread """
def __init__(self, crawl_display):
threading.Thread.__init__(self)
self.crawl_display = crawl_display
def run(self):
self.crawl_display.Show()
затем оба start() в функции OnCrawlClick(). но так же, как я сказал выше, метод не работает.
Может кто-нибудь сказать мне, как правильно делать такие вещи? любая помощь приветствуется!
2 ответа
Вам не разрешен доступ к GUI из неосновного потока. Смотрите документацию вики на это.
Проблема в том, что вы выполняете длинную задачу, и она блокирует основной цикл событий графического интерфейса, поэтому он в основном заморожен. Вам нужно поместить сканер в отдельный поток и использовать поточно-безопасные методы wxPython для обновления GUI. Смотрите вики или этот урок