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

ling1874 2013-10-14 07:01:55
想实现的功能非常简单,前台就一个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()
...全文
474 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
angel_su 2013-10-15
  • 打赏
  • 举报
回复
wx.CallAfter(self.window.DoTest())函数带括号,就叫做调用,去掉红色括弧吧
ling1874 2013-10-15
  • 打赏
  • 举报
回复
@angel_su 咦,难道是我的python2.7安装的有问题? 错误信息: F:\Eclipse_Workspace\workspace_Python\ICON\richtext.py:50: wxPyDeprecationWarning: Using deprecated class PySimpleApp. app=wx.PySimpleApp() Exception in thread Thread-1: Traceback (most recent call last): File "D:\Python27\lib\threading.py", line 808, in __bootstrap_inner self.run() File "F:\Eclipse_Workspace\workspace_Python\ICON\richtext.py", line 15, in run wx.CallAfter(self.window.DoTest()) File "F:\Eclipse_Workspace\workspace_Python\ICON\richtext.py", line 42, in DoTest 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:
# -*- coding: utf-8 -*- 

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):  
        while True:
            wx.CallAfter(self.window.DoTest())
            time.sleep(1)
        
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):
        self.m_richText1.AppendText('hello\n')
    
    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()
    
angel_su 2013-10-15
  • 打赏
  • 举报
回复
我这里改过后就正常,你把报错信息整个贴出来,不要断章取义...
ling1874 2013-10-15
  • 打赏
  • 举报
回复
@angel_su 换成你这样的写法,依然报同样的错误呢 除非我换成textctrl,但是目前我又必须使用richtextctrl,好郁闷啊
ling1874 2013-10-15
  • 打赏
  • 举报
回复
@angel_su 哎呀,太感谢你了! 还是不知道这一点差别的区别呢,一会多看看资料. 说到底还是学艺不精
angel_su 2013-10-14
  • 打赏
  • 举报
回复
非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')

37,719

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧