My widgets are having trouble communicating.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Jory R Ferrell
    New Member
    • Jul 2011
    • 62

    My widgets are having trouble communicating.

    Everytime I run the mainloop, it starts off fine. After pressing the Action button, the program freezes. The second label also fails to change.
    Anyone else getting this problem on their comp or is it the way I wrote the code?

    Code:
    import wx
    import time
    
    
    class LeftPanel(wx.Panel):
        def __init__(self, parent, id):
            wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
            self.text = parent.GetParent().rightPanel.text
            self.text_2 = parent.GetParent().rightPanel.text_2
            button1 = wx.Button(self, -1, 'Count', (10, 10))
            button2 = wx.Button(self, -1, 'Countdown', (10, 60))
            button3 = wx.Button(self, -1, 'Action', (10, 110))
            self.Bind(wx.EVT_BUTTON, self.OnPlus, id=button1.GetId())
            self.Bind(wx.EVT_BUTTON, self.OnMinus, id=button2.GetId())
            self.Bind(wx.EVT_BUTTON, self.button_Pressed, id=button3.GetId())
            self.timed_Out = 1     
    
    
        def OnPlus(self, event):
            value = 1
            for t in range(5000):
                value = value + 1
                time.sleep(1)
                self.text.SetLabel(str(value))
    
        def OnMinus(self, event):
            import math
            value = 60
            for t in range(value):
                value = value - 1
                time.sleep(1)
                self.text.SetLabel(str(value/60) + ':' + str(value%60))
    
            self.timed_Out = 0
            self.text_2.SetLabel(str('End o\'line.'))
    
        def button_Pressed(self, event):
            if self.timed_Out == 1:
                if self.text_2 == 'First':
                    self.text_2.SetLabel('Second')
    
                elif self.text_2 == 'Second':
                     self.text_2.SetLabel('First')
    
    
    
    class RightPanel(wx.Panel):
        def __init__(self, parent, id):
            wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
            self.text = wx.StaticText(self, -1, '0', (10,60))
            self.text_2 = wx.StaticText(self,-1,'First',(10, 120))
    
    class Communicate(wx.Frame):
        def __init__(self, parent, id, title):
            wx.Frame.__init__(self, parent, id, title, size=(600, 200))
            panel = wx.Panel(self, -1)
            self.rightPanel = RightPanel(panel, -1)
            leftPanel = LeftPanel(panel, -1)
            hbox = wx.BoxSizer()
            hbox.Add(leftPanel, 1, wx.EXPAND | wx.ALL, 4)
            hbox.Add(self.rightPanel, 1, wx.EXPAND | wx.ALL, 5)
            panel.SetSizer(hbox)
            self.Centre()
            self.Show(True)
    
    
    
    app = wx.App()
    Communicate(None, -1, 'widgets communicate')
    app.MainLoop()
  • bvdet
    Recognized Expert Specialist
    • Oct 2006
    • 2851

    #2
    If you were in Tkinter, I think I could help you. It may be a problem with time.sleep(). I am guessing - the GUI may not be able to respond to events after time.sleep() is called. Tkinter has a callback method after() which would be appropriate in your example. I think wxPython should have a similar method.

    Comment

    • Jory R Ferrell
      New Member
      • Jul 2011
      • 62

      #3
      Even before I activate the sleep function I can't change the second label using the Action button. Any ideas?

      Comment

      • Smygis
        New Member
        • Jun 2007
        • 126

        #4
        Now I haven't touched programming in about 3 years so I'm really rusty and cant make much sense of you program. But way back when I wrote a small PLC interpreter and had similar issues with the interface that I wrote in wx.

        And then I learned about the wonder that is wx.CallAfter() and everything just worked after that pretty much. Don't remember how it worked though. This was 5 years ago.

        The more i try to figure out what i have forgotten the more I'm thinking that I'm not really helping here

        Comment

        • Jory R Ferrell
          New Member
          • Jul 2011
          • 62

          #5
          Any idea why the second label won't update even before I start the loop?

          Comment

          • Smygis
            New Member
            • Jun 2007
            • 126

            #6
            I have been going through my old app and figuring out how i made it work and this is how i think i did it:

            I have my "compiler/runtime" for PLC code run in a separate thread, i then had a second thread that using wx.CallAfter called functions that checked the state of variables in the runtime thread and updated the UI accordingly.

            This could work for you application as well but needs some reprogramming and i guess is a bit convoluted. the main problem is as bvdet says that time.sleep locks the UI. I spent some time diggin in wx docs and managed to fix it a bit using wx.Yield:
            Code:
            import wx
            import time
            
            
            class LeftPanel(wx.Panel):
                def __init__(self, parent, id):
                    wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
                    self.text = parent.GetParent().rightPanel.text
                    self.text_2 = parent.GetParent().rightPanel.text_2
                    button1 = wx.Button(self, -1, 'Count', (10, 10))
                    button2 = wx.Button(self, -1, 'Countdown', (10, 60))
                    button3 = wx.Button(self, -1, 'Action', (10, 110))
                    self.Bind(wx.EVT_BUTTON, self.OnPlus, id=button1.GetId())
                    self.Bind(wx.EVT_BUTTON, self.OnMinus, id=button2.GetId())
                    self.Bind(wx.EVT_BUTTON, self.button_Pressed, id=button3.GetId())
                    self.timed_Out = 1     
            
            
                def OnPlus(self, event):
                    value = 1
                    for t in range(50):
                        value = value + 1
                        time.sleep(1)
                        wx.Yield()
                        self.text.SetLabel(str(value))
            
                def OnMinus(self, event):
             
                    value = 60
                    for t in range(value):
                        value = value - 1
                        time.sleep(1)
                        wx.Yield()
                        self.text.SetLabel(str(value/60) + ':' + str(value%60))
            
                    self.timed_Out = 0
                    self.text_2.SetLabel(str('End o\'line.'))
            
                def button_Pressed(self, event):
                    if self.timed_Out == 1:
                        if self.text_2 == 'First':
                            self.text_2.SetLabel('Second')
            
                        elif self.text_2 == 'Second':
                             self.text_2.SetLabel('First')
            
            
            class RightPanel(wx.Panel):
                def __init__(self, parent, id):
                    wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
                    self.text = wx.StaticText(self, -1, '0', (10,60))
                    self.text_2 = wx.StaticText(self,-1,'First',(10, 120))
            
            class Communicate(wx.Frame):
                def __init__(self, parent, id, title):
                    wx.Frame.__init__(self, parent, id, title, size=(600, 200))
                    panel = wx.Panel(self, -1)
                    self.rightPanel = RightPanel(panel, -1)
                    leftPanel = LeftPanel(panel, -1)
                    hbox = wx.BoxSizer()
                    hbox.Add(leftPanel, 1, wx.EXPAND | wx.ALL, 4)
                    hbox.Add(self.rightPanel, 1, wx.EXPAND | wx.ALL, 5)
                    panel.SetSizer(hbox)
                    self.Centre()
                    self.Show(True)
            
                    
            
            app = wx.App()
            Communicate(None, -1, 'widgets communicate')
            app.MainLoop()
            After that I'm not sure what happens. With this the application throws errors if you try clicking the other button while countdown/up is ongoing.

            Buy hey its progress right.

            Comment

            • Jory R Ferrell
              New Member
              • Jul 2011
              • 62

              #7
              Alright...btw.. ..whats with your avatar? It seems...'odd'. :/

              Comment

              • Smygis
                New Member
                • Jun 2007
                • 126

                #8
                The base silhouette was the default avatar for new users on TheScripts(.com ). I just 'personalized' it a little bit.

                Comment

                • Jory R Ferrell
                  New Member
                  • Jul 2011
                  • 62

                  #9
                  Any idea why my second label isn't updating before I activate the loop though?

                  Comment

                  Working...