Frage

in my GUI with wxPython if have to do some calculations which can take some time. So I want to start them in a seperate Thread and show a window in the GUI that prints that the program is calculating. The main windows should be disabled during this. So that's my code:

import time
import threading

import wx

def calculate():
    # Simulates the calculation
    time.sleep(5)
    return True

class CalcFrame(wx.Frame):

    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent=None, id=-1, title="Calculate")
        # Normally here are some intctrls, but i dont show them to keep it easy
        self.panel = wx.Panel(parent=self, id=-1)
        self.createButtons()

    def createButtons(self):
        button = wx.Button(parent=self.panel, id=-1, label="Calculate")
        button.Bind(wx.EVT_BUTTON, self.onCalculate)

    def onCalculate(self, event):
        calcThread = threading.Thread(target=calculate)
        checkThread = threading.Thread(target=self.checkThread, args=(calcThread,))
        self.createWaitingFrame()
        self.waitingFrame.Show(True)
        self.Disable()
        calcThread.run()
        checkThread.run()

    def createWaitingFrame(self):
        self.waitingFrame = wx.MiniFrame(parent=self, title="Please wait")
        panel = wx.Panel(parent=self.waitingFrame)
        waitingText = wx.StaticText(parent=panel, label="Please wait - Calculating", style=wx.ALIGN_CENTER)

    def checkThread(self, thread):
        while thread.is_alive():
            pass
        print "Fertig"
        self.waitingFrame.Destroy()
        self.Enable()

app = wx.PySimpleApp()
frame = CalcFrame(parent=None, id=-1)
frame.Show()
app.MainLoop()

But my problem is now, that if i press the "Calculate" button, the waitingFrame isnt't shown right, I can't see the text. I also cant move/maximize/minimize the main window. Can you help me? Thank you in advance :)

War es hilfreich?

Lösung

you should never update the gui in a thread other than the main thread .... Im pretty sure the docs for wxPython mention this in several places .. it is not thread safe and your gui gets in broken states ...

instead I believe you are supposed to do something like

def thread1():
     time.sleep(5)
     return True

def thread2(t1,gui):
    while thread.is_alive():
        pass
    print "Fertig"
    wx.CallAfter(gui.ThreadDone)

class MyFrame(wx.Frame):
   def startThread(self):
      calcThread = threading.Thread(target=thread1)
      checkThread = threading.Thread(target=thread2, args=(calcThread,self))
   def ThreadDone(self):
       print "Both threads done???"
       print "Now modify gui from main thread(here!)"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top