Rares Dima
Rares Dima

Reputation: 1747

wxPython panel not showing at Show()

So I have a small app. The gist of it is just a window with a button in the center of the main frame. When you click the button, the button gets hidden and a gauge/loading bar appears in the center of the main frame and fills up as it does some computations( the filling up part is not implemented yet, at the moment it's just an empty gauge that sits there).

The button and the gauge are each implemented in their own panels, and to "switch" between them I just disable an hide the button panel and then enable and show the gauge panel. To switch back I just reverse that process. Pretty straight forward.

Now, as a test I wanted the button, when clicked, to just switch to the gauge for a couple seconds and the switch back(using Sleep()).

This is the relevant code(please ask for more if you consider it would be relevant):

import wx
import time
import gui_base


class MainFrame(gui_base.main_frame):
        def __init__(self):
                super(MainFrame, self).__init__(None)
                self.set_state_pre_compare()

        def set_state_pre_compare(self):
                self.panel_in_compare_panel.Disable()
                self.panel_in_compare_panel.Hide()
                print('done hiding in')
                self.panel_pre_compare_panel.Enable()
                self.panel_pre_compare_panel.Show()
                print('done enabling pre')
                self.Layout()

        def set_state_in_compare(self):
                self.panel_pre_compare_panel.Disable()
                self.panel_pre_compare_panel.Hide()
                print('done hiding pre')
                self.panel_in_compare_panel.Enable()
                self.panel_in_compare_panel.Show()
                print('done enabling in')
                self.Layout()

        def on_compare_button_click(self, event):
                self.set_state_in_compare()
                time.sleep(2.5)
                self.set_state_pre_compare()


if __name__ == '__main__':
    app = wx.App(True)
    frame = MainFrame()
    frame.Show()
    app.MainLoop()

The pre and in panels refer to "pre computation"(panel with the button, computations not yet started) and "in computation"(panel with the gauge, computations started)

My big problem is this: the app starts up fine, I click the button, the button disappears just fine, however the loading bar does not show at all, and after a few seconds the button shows back up.

I also used some print statements to check if the functions complete/hand somewhere but all seems great, nothing hangs, everything completes nicely.

Also if I set the initial state of the app to be with the gauge showing(meaning there is no way to switch to the button) the gauge shows just fine.

The conclusion I get are that the GUI elements themselves are okay since at startup, if i start the program with either of the 2 states as the initial one, that state shows up just fine.

Also that the switching function, to some degree works, although I am not sure to what extent.

May bottom question is: why does it not switch between the states nicely if both panels show up just fine if they are set as the startup panel? And what would be the fix?

Thank you in advance!

EDIT:

I modified the code like this:

 def on_compare_button_click(self, event):
                event.Skip()
                self.set_state_in_compare()
                self.delay()


 def delay(self):
                for i in range(1500):
                        print(i)

To simulate some delay and what I noticed is that the frame contents only really update at the end of that function. If I don't switch back to the button panel, the gauge will work just fine, but on pressing the button, the button panel gets hidden, the show/enable for the gauge gets called and completes, but the gauge will not show up(the whole frame will be a blank window) until the delay function is over. I have tried putting set_state or delay in their own threads, or both in his own thread, nut nothing seems to change what happens.

Why does this happen? And how can I make the GUI actually update when it is meant to(when the set_state functions get called)?

Upvotes: 0

Views: 1602

Answers (1)

Rares Dima
Rares Dima

Reputation: 1747

I figured it out. From what I can understand, the GUI only gets updated when the function completed. To force a GUI update, calling self.Layout() and self.Update() does the trick.

Leaving this here in case someone might stumble into the same thing.

Upvotes: 1

Related Questions