1

我正在尝试更新textctrlwxpython 中的 a,而一个长时间运行的线程正在查找某种信息。在用户将焦点转移到另一个窗口之前,它工作得很好,然后在返回到 wxpython 脚本时,GUI 在线程完成之前没有响应。

有没有办法返回到这个脚本并仍然看到textctrl动画光标的更新?

这是代码:

#!/usr/bin/env python
import wx
import thread
import Queue
from time import sleep

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_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
                bSizer2 = wx.BoxSizer( wx.VERTICAL )

                self.m_button1 = wx.Button( self.m_panel1, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0 )
                bSizer2.Add( self.m_button1, 0, wx.ALL, 5 )

                self.m_panel1.SetSizer( bSizer2 )
                self.m_panel1.Layout()
                bSizer2.Fit( self.m_panel1 )
                bSizer1.Add( self.m_panel1, 1, wx.EXPAND |wx.ALL, 5 )

                self.m_panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
                bSizer3 = wx.BoxSizer( wx.VERTICAL )

                self.m_textCtrl1 = wx.TextCtrl( self.m_panel2, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE )
                bSizer3.Add( self.m_textCtrl1, 1, wx.ALL|wx.EXPAND, 5 )

                self.m_panel2.SetSizer( bSizer3 )
                self.m_panel2.Layout()
                bSizer3.Fit( self.m_panel2 )
                bSizer1.Add( self.m_panel2, 1, wx.EXPAND |wx.ALL, 5 )

                self.SetSizer( bSizer1 )
                self.Layout()

                self.Centre( wx.BOTH )

                # Connect Events
                self.m_button1.Bind( wx.EVT_BUTTON, self.do_something )

        def __del__( self ):
                pass


        # Virtual event handlers, overide them in your derived class
        def do_something( self, event ):
                event.Skip()



class MyFrame( MyFrame1 ):
    def __init__( self, parent ):
        MyFrame1.__init__( self, parent )

    def do_something(self, event):
        self.Result = Queue.Queue()
        thread.start_new_thread(self.do_loop, ())
        self.m_textCtrl1.AppendText("searching for something... ")
        self.found= 0
        for character in self.cursor():
            self.m_textCtrl1.AppendText(character)
            self.Update()
            sleep(0.1)
            self.m_textCtrl1.Undo()
            if (self.found == 1):
                self.m_textCtrl1.AppendText('\n')
                break
        num = self.Result.get()
        print num

    def cursor(self):
        characters='.oOo'
        i = 0
        while 1:
            yield characters[i]
            i = (i + 1) % len(characters)

    def do_loop(self):
        x = 0
        while (x < 20007):
            print x
            x = x + 1
            if x == 20000:
                self.Result.put(x)
                self.found = 1
                break

class threadtest(wx.App):
    def OnInit(self):
        self.m_frame = MyFrame(None)
        self.m_frame.Show()
        self.SetTopWindow(self.m_frame)
        return True

app = threadtest(0)
app.MainLoop()
4

1 回答 1

0

这是基于匿名 Coward 评论的解决方案。我将按钮事件中的所有内容都移到了一个线程中。让我知道是否有更好的方法来做到这一点。

#!/usr/bin/env python
import wx
import thread
import Queue
from time import sleep

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_panel1 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
                bSizer2 = wx.BoxSizer( wx.VERTICAL )

                self.m_button1 = wx.Button( self.m_panel1, wx.ID_ANY, u"MyButton", wx.DefaultPosition, wx.DefaultSize, 0 )
                bSizer2.Add( self.m_button1, 0, wx.ALL, 5 )

                self.m_panel1.SetSizer( bSizer2 )
                self.m_panel1.Layout()
                bSizer2.Fit( self.m_panel1 )
                bSizer1.Add( self.m_panel1, 1, wx.EXPAND |wx.ALL, 5 )

                self.m_panel2 = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
                bSizer3 = wx.BoxSizer( wx.VERTICAL )

                self.m_textCtrl1 = wx.TextCtrl( self.m_panel2, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, wx.TE_MULTILINE )
                bSizer3.Add( self.m_textCtrl1, 1, wx.ALL|wx.EXPAND, 5 )

                self.m_panel2.SetSizer( bSizer3 )
                self.m_panel2.Layout()
                bSizer3.Fit( self.m_panel2 )
                bSizer1.Add( self.m_panel2, 1, wx.EXPAND |wx.ALL, 5 )

                self.SetSizer( bSizer1 )
                self.Layout()

                self.Centre( wx.BOTH )

                # Connect Events
                self.m_button1.Bind( wx.EVT_BUTTON, self.do_something )

        def __del__( self ):
                pass


        # Virtual event handlers, overide them in your derived class
        def do_something( self, event ):
                event.Skip()



class MyFrame( MyFrame1 ):
    def __init__( self, parent ):
        MyFrame1.__init__( self, parent )

    def do_something(self, event):
        thread.start_new_thread(self.do_something_thread, ())

    def do_something_thread(self):
        self.Result = Queue.Queue()
        thread.start_new_thread(self.do_loop, ())
        self.m_textCtrl1.AppendText("searching for something... ")
        self.found= 0
        for character in self.cursor():
            self.m_textCtrl1.AppendText(character)
            self.Update()
            sleep(0.1)
            self.m_textCtrl1.Undo()
            if (self.found == 1):
                self.m_textCtrl1.AppendText('\n')
                break
        num = self.Result.get()
        print num

    def cursor(self):
        characters='.oOo'
        i = 0
        while 1:
            yield characters[i]
            i = (i + 1) % len(characters)

    def do_loop(self):
        x = 0
        while (x < 20007):
            print x
            x = x + 1
            if x == 20000:
                self.Result.put(x)
                self.found = 1
                break

class threadtest(wx.App):
    def OnInit(self):
        self.m_frame = MyFrame(None)
        self.m_frame.Show()
        self.SetTopWindow(self.m_frame)
        return True

app = threadtest(0)
app.MainLoop()
于 2012-11-16T23:43:56.027 回答