SOLVED vanilla Window opening 2nd Window



  • Hi, I have a vanilla Window that calls another Window when a Button is pressed (for example, to edit preferences).

    Is it better / preferred / more "canonical" to initialize and open the second Window once (and use the button only to run .show() and .hide()), or to initialize and open a new second Window (and close it completely) when the button is pressed?

    A couple of examples to show what I mean below.

    A) First Window initializes second Window on __init__; button shows/closes

    from prefWindow import PrefWindow
    class MainWindow:
        def __init__(self):
            self.w = Window((200, 200))
            self.w.prefButton = Button((10, 10, -10, 20),
                                       "Open Pref",
                                       callback=self.prefCB)
    
            self.prefOpened = False
    
            self.prefWindow = PrefWindow()
            self.prefWindow.w.open()
            self.prefWindow.w.hide()
    
        def prefCB(self, sender):
            if self.prefOpened:
                self.prefWindow.hide()
            else:
                self.prefWindow.w.show()
    
            self.prefOpened = !self.prefOpened
    

    B) Button initializes new second Window every time

    from prefWindow import PrefWindow
    class MainWindow:
        def __init__(self):
            self.w = Window((200, 200))
            self.w.prefButton = Button((10, 10, -10, 20),
                                       "Open Pref",
                                       callback=self.prefCB)
    
            self.prefOpened = False
    
        def prefCB(self, sender):
            if self.prefOpened:
                self.prefWindow.w.close()
            else:
                self.prefWindow = PrefWindow()
                self.prefWindow.w.open()      
    
            self.prefOpened = !self.prefOpened    
    

    I've gotten both versions to work, so I'm just wondering if there's one way that's preferred. Thanks!



  • Oh, that's a good one. Thanks @frederik!


  • admin

    maybe the easiest way todo is use a subclass like RoboFont is using for some windows:

    from mojo.UI import ShowHideWindow
    # a show hide window is a special window that disables the close callback and just hides the window on close.
    w = ShowHideWindow((100, 100))
    w.open()
    # we close
    w.close()
    # and are able to open it again
    w.open()
    # this also works
    w.hide()
    w.show()
    

    hope this helps to have only one instance of your window

    good luck



  • Thanks for the pointers @frederik & @gferreira. Just to clarify... and maybe you guys can let me know if this way of thinking about things doesn't make sense.

    I'm building something that has a main Window, with a list of objects (using vanilla.List), and when the user clicks on a button, a second Window (or can be a Sheet) opens, where they can input some preferences.

    In my original thinking, the preference Window "belongs" to the object being edited, so I would initialize it every time the user hits the button. I only want one preference Window to be open at a time, so I use a flag to make sure the user can't open another preference Window.

    And this is where I started thinking of just using show() and hide(). Since I only want one preference Window anyway, it seems kind of strange to have to initialize and open one at every button click, and maybe I should just make one preference Window that's always open but is sometimes hidden. (In this case, the preference Window uses closable=False.)

    Either way, I'm passing in data from the object to the pref Window. In the first case, when initializing:

    prefWindow = PrefWindow(some, data, here)
    prefWindow.w.open()
    

    In the second case, I initialize with nothing and then have a method to update:

    prefWindow = PrevWindow()
    ...
    
    prefWindow.update(some, data, here)
    prefWindow.w.show()
    

  • admin

    fyi: a drawer is not advised anymore by the Human Interface guidelines.



  • depending on what you’re trying to build, you might also consider using a vanilla Sheet or Drawer. they work like separate windows attached to the parent window.



  • @frederik Good points, thanks. I was only using the prefOpened flags as examples above.

    I've been using the 2nd method (not using the flag, just initializing a new PrefWindow() every time I need that window). But because you can't reopen a closed window, like you said, I make a new PrefWindow() when the button is clicked. I'm just not sure if it's strange to be initializing all of the vanilla UI components over and over again?

    I'm thinking of switching to the first option (initialize once, and use show() and hide()), but also not sure if it's weird to have a hidden window in the "background."


  • admin

    Its depends on what you would like to achieve. But take note that a window can be closed in different ways, ⌘ + w or the red left top button... where you are not able to set the prefOpened attribute.

    Also you can not reopen a closed window. An other option is to overwrite the close callback in the window class used in the vanilla.Window object and just order out instead of closing the window.

    good luck!


Log in to reply