首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > perl python >

这么一个简单的多线程python为何出错呢

2013-10-16 
这样一个简单的多线程python为何出错呢?本帖最后由 ling1874 于 2013-10-14 19:15:21 编辑想实现的功能非

这样一个简单的多线程python为何出错呢?
本帖最后由 ling1874 于 2013-10-14 19:15:21 编辑 想实现的功能非常简单,前台就一个richtextctrl的控件.
然后后台进程每一秒钟让其增加显示一条重复的信息.

但是运行之后总是会出错呢:

self.m_richText1.AppendText('hello\n')
  File "D:\Python27\lib\site-packages\wx-2.9.4-msw\wx\_core.py", line 13113, in AppendText
    return _core_.TextEntryBase_AppendText(*args, **kwargs)
PyAssertionError: C++ assertion "wxWindow::FindFocus() == GetWindow()" failed at ..\..\src\msw\caret.cpp(164) in wxCaret::DoMove(): how did we lose focus?

为嘛会出这个错误呢? 谢谢


Code如下:

import wx,threading
import wx.xrc
import wx.richtext
import time

class MainThread(threading.Thread):
    def __init__(self,window):
        threading.Thread.__init__(self)
        self.window=window
        
    def run(self):  
        self.window.DoTest()
        
class MyFrame1 ( 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 )
        
        bSizer1 = wx.BoxSizer( wx.VERTICAL )
        
        self.m_richText1 = wx.richtext.RichTextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0|wx.VSCROLL|wx.HSCROLL|wx.NO_BORDER|wx.WANTS_CHARS )
        bSizer1.Add( self.m_richText1, 1, wx.EXPAND |wx.ALL, 5 )
        
        
        self.SetSizer( bSizer1 )
        self.Layout()
        
        self.Centre( wx.BOTH )
    
    def __del__( self ):
        pass
    
    def DoTest(self):
        while True:
            self.m_richText1.AppendText('hello\n')
            time.sleep(1)
    
    def Start(self):
        self.mainthread=MainThread(self)
        self.mainthread.setDaemon(True)
        self.mainthread.start()

if __name__=='__main__':
    app=wx.PySimpleApp()
    my=MyFrame1(None)
    my.Show()
    my.Start()
    app.MainLoop()

[解决办法]
非UI线程忌讳直接调用UI函数,应该用发消息的方式通知UI线程自己去做更新,一般简单情况下用wx.CallAfter函数发消息,另外DoTest函数UI线程本身可以调用,不要用while true阻塞式代码,把它挪到线程里...
[code=python]class MainThread(threading.Thread):

    ...
         
    def run(self):  
        while 1:
            wx.CallAfter(self.window.DoTest)
            time.sleep(1)
         
class MyFrame1 ( wx.Frame ):

    ....
     
    def DoTest(self):
        self.m_richText1.AppendText('hello\n')

热点排行