how does one tell the screen to Refresh from within another module?

I have the standard:

from RegWindow import *

class main_window(wx.Frame):
    def __init__(self, parent, title):
        """."""
        # Actual Window size on screen
        fullsize=wx.Size(850,900)
        # Create our main window
        wx.Frame.__init__(self, parent, title=title, size=fullsize,
                          style=wx.DEFAULT_FRAME_STYLE)

        rw=RegWindow(self.scroll, ID=-1, Registration=rg, BackgroundColour=AssignColorToSeNo(rg.Rg_SeNo))
        weekoverviewSizer.Add(rw, pos=(srow,col), span=(erow,1), flag=wx.EXPAND)

        self.scroll.SetSizer(weekoverviewSizer)
        self.scroll.SetupScrolling(self, rate_x=20, rate_y=50)
        fullsize=wx.Size(1000,900)
        self.Centre()

class App(wx.App):
    """wxProject Application."""
    def OnInit(self):
        """Create the wxProject Application."""
        self.frame = main_window(None, 'Planning Assistant')
        self.frame.Show(True)
        return True

if __name__ == '__main__':
    app = App(redirect=False)
    app.MainLoop()

in one module. Then I have the following in RegWindow.py:

class RegWindow(wx.Panel):
    def __init__(self, parent, ID=-1, Registration=None,
                 pos=wx.DefaultPosition, size=(85,2), BackgroundColour="white"):
        wx.Panel.__init__(self, parent, ID, pos, size, wx.RAISED_BORDER)
        self.Registration=Registration
        self.BackgroundColour=BackgroundColour
               self.SetBackgroundColour(BackgroundColour)

        self.Bind(wx.EVT_CONTEXT_MENU, self.OnRightMouseButtonDownOnRegistration)

    def OnRightMouseButtonDownOnRegistration(self, event):
        pos = event.GetPosition()
        print event.GetId(), pos
        RgNo=IDtoRgNoDict[event.GetId()][1]

        pos = self.ScreenToClient(pos)

        self.popupmenu = wx.Menu()
               self.sessubmenu = wx.Menu()
        self.regsubmenu = wx.Menu()

        reg=regsdict[RgNo]

        for room in reg.Session.getAvailableRooms():
            item=self.sessubmenu.Append(-1, room)
            IDtoRgNoDict[item.GetId()]=['session', RgNo]
            self.sessubmenu.Bind(wx.EVT_MENU, self.OnRoomSelected, item)
            self.popupmenu.Bind(wx.EVT_MENU, self.OnRoomSelected, item)

        for room in reg.getAvailableRooms():
            item=self.regsubmenu.Append(-1, room)
            IDtoRgNoDict[item.GetId()]=['registration', RgNo]
            self.regsubmenu.Bind(wx.EVT_MENU, self.OnRoomSelected, item)
            self.popupmenu.Bind(wx.EVT_MENU, self.OnRoomSelected, item)

        item = self.popupmenu.AppendMenu(-1, 'Move entire session', self.sessubmenu)
        item = self.popupmenu.AppendMenu(-1, 'Move only this registration', self.regsubmenu)
        item = self.popupmenu.Append(-1, 'Add comment')
        self.popupmenu.Bind(wx.EVT_MENU, self.OnAddComment, item)
        item = self.popupmenu.Append(-1, 'Assign PCs')
        item = self.popupmenu.Append(-1, 'Assign tasks')
        item = self.popupmenu.Append(-1, 'Show tasks status')

        self.PopupMenu(self.popupmenu, pos)

    def OnRoomSelected(self, event):
        ''' The user selected a room number in a pop up menu, now we need to move the applicable session
            or registration to this room
        '''
        self.SetFocus()

        #The text of the item (submenu) contains the room number
        item=self.popupmenu.FindItemById(event.GetId())
        Room=item.GetText()
        # The RgNo-IDOFFSET was stored in a dictionary, indexed on the ID that was assigned to the submenu item
        RgNo=IDtoRgNoDict[event.GetId()][1]
        # whether it concerns a Registration or an entire Session that needs to be moved is stored there as well
        type=IDtoRgNoDict[event.GetId()][0]
        sizer=self.GetContainingSizer()
        if type == 'session':
            Sess=sessdict[regsdict[RgNo].Rg_SeNo]
            Sess.setRoom(Room=Room)
                       for rg in Sess.Registrations:
                rw=RgNoToRWDict[rg.RgNo]
                sizer.Detach(rw)
                srow, erow, col = CalculateRowCol(rg, rg.Session.SeLoc_CoNo)

                RgNoToRWDict[rg.RgNo]=sizer.Add(rw,pos=(srow,col), span=(erow,1), flag=wx.EXPAND)
                sizer.Layout()

        if type == 'registration':
            Reg=regsdict[RgNo]
            Reg.setRoom(Room=Room)
            # Detach our RegWindow from its current position
            sizer.Layout()
            rg=regsdict[RgNo]

            srow, erow, col = CalculateRowCol(rg, rg.Session.SeLoc_CoNo)
                       sizer.Add(self,pos=(srow,col), span=(erow,1), flag=wx.EXPAND)

        # Redraw the screen, DOESN'T WORK, even when done twice for good measure...
        sizer.Layout()
# print dir(wxPlanningAssistant.App.frame)
        app.frame.Refresh() # DOESN'T WORK, NameError: global name 'app' is not defined. It does exactly what I need from within PyCrust though.
# wxPlanningAssistant.App.frame.Layout()

When a room is selected in the context sensitive menu. The RegWindow is moved to another spot in the sizer. Then the screen needs to be refreshed. If I do it manually by resizing or by maximizing, everything looks OK, but I want to do it programmatically. The problem is that from within the OnRoomSelected handler I cannot get a reference to the frame.

Do I have to import the main module into RegWindow.py? That seems like spaghetti to me, two modules each importing the other and it doesn't work then either. With something that is contained in a sizer, it's possible to get the containing sizer object, but there is no method on the sizer object to obtain the containing panel object.

I hope somebody can help me with this and I also hope I didn't take out too much of code for the example. I tried to just post the essential bits to show what I'm trying to achieve.

Kind regards,

Jo

Hi Jo,

instead of:
app.frame.Refresh()

you could do:
wx.GetApp().frame.Refresh()

Or in your app you set the topwindow:

       self.frame.Show(True)
       self.SetTopWindow(self.frame)

wx.GetTopWindow().Refresh()

Did not try this out, but hopefully it is enough to get you going.
Werner

Jo wrote:

When a room is selected in the context sensitive menu. The RegWindow is moved to another spot in the sizer. Then the screen needs to be refreshed. If I do it manually by resizing or by maximizing, everything looks OK, but I want to do it programmatically. The problem is that from within the OnRoomSelected handler I cannot get a reference to the frame.

  frame = wx.GetTopLevelParent(self)

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

Jo wrote:

When a room is selected in the context sensitive menu. The RegWindow is moved to another spot in the sizer. Then the screen needs to be refreshed. If I do it manually by resizing or by maximizing, everything looks OK, but I want to do it programmatically. The problem is that from within the OnRoomSelected handler I cannot get a reference to the frame.

    frame = wx.GetTopLevelParent(self)

Hi Robin,

That did the trick. Now the window is redrawn correctly, but the sizer still behaves erratically (didn't mention that yet). When I detach a RegWindow and then place it somewhere else, it happens very often that a lot of sizer cells are added on top and very rarely on the left. Maximizing the window solves this. When the window is maximized, putting it back to Window mode solves it too. So the app/window/sizer knows how it should be, but it doesn't actually do what it's supposed to do. Maybe I should maximize the screen programmatically and then put it back to where it was?

Many thanks for your answer and also for the great book which I'm using extensively.

Jo

Werner F. Bruhin wrote:

Hi Jo,

instead of:
app.frame.Refresh()

you could do:
wx.GetApp().frame.Refresh()

Or in your app you set the topwindow:

      self.frame.Show(True)
      self.SetTopWindow(self.frame)

wx.GetTopWindow().Refresh()

Did not try this out, but hopefully it is enough to get you going.
Werner

Hi Werner,

It certainly put me on the right track. Many thanks,

Jo

Jo wrote:

Robin Dunn wrote:

Jo wrote:

When a room is selected in the context sensitive menu. The RegWindow is moved to another spot in the sizer. Then the screen needs to be refreshed. If I do it manually by resizing or by maximizing, everything looks OK, but I want to do it programmatically. The problem is that from within the OnRoomSelected handler I cannot get a reference to the frame.

    frame = wx.GetTopLevelParent(self)

Hi Robin,

That did the trick. Now the window is redrawn correctly, but the sizer still behaves erratically (didn't mention that yet). When I detach a RegWindow and then place it somewhere else, it happens very often that a lot of sizer cells are added on top and very rarely on the left. Maximizing the window solves this. When the window is maximized, putting it back to Window mode solves it too. So the app/window/sizer knows how it should be, but it doesn't actually do what it's supposed to do. Maybe I should maximize the screen programmatically and then put it back to where it was?

You probably just need to trigger a layout. Since that is normally done in a EVT_SIZE event you won't get an autolayout until the next time that the window is sized. That's why your layout corrects itself when the frame is resized. Try doing frame.Layout() or perhaps frame.GetSizer().Layout() and see if that helps.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!