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. Смотрите вики или этот урок

Другие вопросы по тегам