Почему этот способ завершения потока не работает?

1

Я только что вышел с моим noob способом прекратить поток, но я не знаю, почему он не работает. Кто-нибудь, пожалуйста, помогите мне?

Вот мой пример кода:

import wx
import thread
import time
import threading

class TestFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, parent = None, id = -1, title = "Testing", pos=(350, 110), size=(490, 200), style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.MINIMIZE_BOX)
        self.panel = wx.Panel(self)

        self.stop = False

        self.StartButton = wx.Button(parent = self.panel, id = -1, label = "Start", pos = (110, 17), size = (50, 20))
        self.MultiLine = wx.TextCtrl(parent = self.panel, id = -1, pos = (38, 70), size = (410, 90), style = wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_AUTO_URL)


        self.Bind(wx.EVT_BUTTON, self.OnStart, self.StartButton)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

    def OnStart(self, event):
        self.StartButton.Disable()
        self.NewThread = threading.Thread(target = self.LongRunning)
        self.NewThread.start()

    def OnClose(self, event):
        self.stop = True
        BusyBox = wx.BusyInfo("Just a moment please!", self)
        wx.Yield()

        while True:
            try:
                if not self.NewThread.isAlive():
                    self.Destroy()
                    break
                time.sleep(0.5)
            except:
                self.Destroy()
                break

    def LongRunning(self):
        Counter = 1

        while True:
            time.sleep(2)
            print "Hello, ", Counter
            self.MultiLine.AppendText("hello, " + str(Counter) + "\n") #If you comment out this line, everything works fine. Why can't I update the fame after I hit the close button?
            Counter = Counter + 1
            if self.stop:
                break

class TestApp(wx.App):
    def OnInit(self):
        self.TestFrame = TestFrame()
        self.TestFrame.Show()
        self.SetTopWindow(self.TestFrame)
        return True

def main():
    App = TestApp(redirect = False)
    App.MainLoop()

if __name__ == "__main__":
    main()

Как вы можете видеть в моем коде, в потоке есть бесконечный цикл, и я говорю, что поток должен выходить из цикла, как только я нажимаю кнопку закрытия. Но проблема в том, что каждый раз, когда я нажимаю кнопку закрытия, кажется, что код застрял в строке self.MultiLine.AppendText("hello, " + str(Counter) + "\n"), я не знаю почему. Кто-нибудь может помочь?

  • 0
    if not self.NewThread.isAlive(): Какую версию python вы используете ?? 2,5? Вы должны обновить свою версию Python в первую очередь!
  • 0
    Я уже на питоне 2.7
Теги:
wxpython
wx.textctrl

2 ответа

2
Лучший ответ

Попробуйте использовать безопасный поток, например wx.CallAfter при обновлении многострочного файла.

 def LongRunning(self):
     Counter = 1

     while True:
         time.sleep(2)
         print "Hello, ", Counter

         wx.CallAfter(self.updateMultiLine, "hello, " + str(Counter) + "\n")
         Counter = Counter + 1
         if self.stop:
             break

 def updateMultiLine(self, data):
     self.MultiLine.AppendText(data)
  • 0
    Вы ответили на довольно много моих глупых вопросов, так что большое спасибо за ваше терпение!
  • 0
    @Shane: Добро пожаловать, всегда рад помочь! :)
1

В целом с инструментами GUI только один поток должен иметь доступ к функциям GUI. Исключением является wx.CallAfter

Как вы должны знать, дефекты программного обеспечения можно разделить на три группы:

  • Ваши ошибки.
  • Их ошибки.
  • Темы.

;)

  • 0
    Я просто отключил кнопку запуска, как только поток запускается, это один поток, обращающийся к функциям GUI, все еще с той же проблемой ... Кто-нибудь объяснит мне причину?
  • 1
    @Shane: «одна нить» не означает «одна нить за раз». Это означает, что независимо от того, какой поток запускает цикл обработки событий, он должен быть единственным потоком, который напрямую обновляет интерфейс пользователя. Вы не можете создать отдельный поток, а затем переключиться на него, который обновляет пользовательский интерфейс.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню