-1

I'm working on a Python project in which I have to represent a GUI-structure in my code. It looks like this:

  • window1 (containing button1, button2, button3, dialog1, ...)
  • window2 (containing button4, button5, dialog2, list1, ...)

So there is a number of windows, each with different content, and different functionality behind the different elements. Each window can have different custom methods that should work only there.

Now I have two possibilities:

The first:

class Window1(object):
    def __init__(self):
        self.elements = {"button1":button1,"button2":button2,...}

    def customMethod(self):
        print "do custom"

class Window2(object):
    def __init__(self):
        self.elements = {"button4":button4,"button5":button5,...}

    def otherCustomMethod(self):
        print "do other custom"

...
window1 = Window1()
window2 = Window2()

But if I do this, there will be many classes, one for each window, and I only need one instance of each window. So the second possibility would be to create the right objects on the fly:

# create template class
class WindowGeneric(object):
    pass

# create first window
window1 = WindowGeneric()
window1.elements = {"button4":button4,"button5":button5,...}

def customMethod(self):
    print "do custom"

window1.customMethod = customMethod.__get__(window1, WindowGeneric) #bind to instance

#create second window
window2 = WindowGeneric()
window2.elements = {"button4":button4,"button5":button5,...}

def otherCustomMethod(self):
    print "do other custom"

window1.otherCustomMethod = otherCustomMethod.__get__(window2, WindowGeneric) #bind to instance

But this solution looks ugly, too, because of the get "hacking" stuff.

It's really all about the creation of the objects, the elements of the windows is known before runtime and will not change during runtime.

So is there any better way to do this?

Edit: To clarify things a bit: I only want to create a lot of similar but not equal objects (they can have different methods and vars inside), but I don't know if it is better to create a new class for every object (version 1) or to create the objects by having a dummy object and adding the individual functionality afterwards (version 2).

JayTheKay
  • 1,168
  • 9
  • 20

3 Answers3

0

It's very difficult to tell with your code snippet, but perhaps you could solve this problem using inheritance...

class BaseWindow(object):
     def __init__(self,elements):
        self.elements = elements
     def common_method1(self,...):
        ...
     def common_method2(self,...):
        ...

class Window1(BaseWindow):
     def __init__(self):
        BaseWindow.__init__(self,{"button1":button1,"button2":button2,...})
mgilson
  • 264,617
  • 51
  • 541
  • 636
  • This would be solution 1, so I would have classes Window1 to WindowN with only one instance of each class. I don't know if that's the best way. – JayTheKay Oct 16 '12 at 14:34
0

What you need here is a Factory Pattern. Create a FactoryWindow Class, and add a classmethod createwindow to instantiate a window based on some Window ID. Maintain a dictionary of all Windows instantiated and if you are instantiating an already existing one, return the previous instance instead of creating a new one

class FactoryWindow(object):
    Windows = {1:Window1,2:Window2}
    window_instance = {}
    @classmethod
    def CreateWindow(cls,win_no):
        if win_no in cls.window_instance:
            return cls.window_instance[win_no]
        else:
            cls.window_instance[win_no] = cls.Windows[win_no]()
            return cls.window_instance[win_no]


>>> window1 = FactoryWindow.CreateWindow(1)
>>> window2 = FactoryWindow.CreateWindow(2)
>>> window3 = FactoryWindow.CreateWindow(1)
>>> id(window3) == id(window1)
True
Abhijit
  • 55,716
  • 14
  • 105
  • 186
  • But then I would still have to define all the Window-classes, if possible, I don't want to create a new class for every window, at least not by hand. – JayTheKay Oct 16 '12 at 14:40
0

Separating the presentation from the logic as much as possible is generally cleaner.

Consider a generic window which is just/mostly a dumb container of interface elements, plus whatever callbacks you need (they can just be functions or callable objects passed in to the __init__ method, you don't need to hack new methods into the object from outside).

This means:

  • you can easily build your dumb windows from config (XML, or whatever) if you have a lot of them, and hence avoid the need to mix hardcoded layout information with your logic
  • you can easily mock a window, or just invoke your callback directly, in order to run tests without displaying GUI elements
  • you can port to different GUI systems much more easily, if you need to
Useless
  • 55,472
  • 5
  • 73
  • 117