-1

我正在开发一个 Python 项目,我必须在我的代码中表示一个 GUI 结构。它看起来像这样:

  • 窗口 1(包含按钮 1、按钮 2、按钮 3、对话框 1、...)
  • window2(包含 button4、button5、dialog2、list1、...)

所以有许多窗口,每个窗口都有不同的内容,不同元素背后的功能也不同。每个窗口都可以有不同的自定义方法,这些方法只能在那里工作。

现在我有两种可能:

首先:

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()

但是如果我这样做,就会有很多类,每个窗口一个,我只需要每个窗口的一个实例。所以第二种可能性是动态创建正确的对象:

# 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

但是这个解决方案看起来也很丑陋,因为得到“黑客”的东西。

这实际上是关于对象的创建,窗口的元素在运行之前是已知的,并且在运行期间不会改变。

那么有没有更好的方法来做到这一点?

编辑:澄清一下:我只想创建很多相似但不相等的对象(它们内部可以有不同的方法和变量),但我不知道为每个对象创建一个新类是否更好(版本 1)或通过拥有一个虚拟对象并在之后添加单个功能来创建对象(版本 2)。

4

3 回答 3

0

很难用你的代码片段来判断,但也许你可以使用继承来解决这个问题......

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,...})
于 2012-10-16T13:04:07.220 回答
0

您在这里需要的是工厂模式。创建一个 FactoryWindow 类,并添加一个类方法createwindow来实例化一个基于一些Window ID. 维护所有已实例化的 Windows 的字典,如果您正在实例化一个已经存在的实例,则返回前一个实例而不是创建一个新实例

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
于 2012-10-16T13:16:31.683 回答
0

尽可能将表示与逻辑分开通常更清晰。

考虑一个通用窗口,它只是/主要是界面元素的哑容器,加上您需要的任何回调(它们可以只是传递给__init__方法的函数或可调用对象,您不需要从外部将新方法破解到对象中)。

这表示:

  • 如果您有很多配置(XML 或其他),您可以轻松地从配置(XML 或其他)构建您的哑窗口,从而避免将硬编码的布局信息与您的逻辑混合在一起
  • 您可以轻松地模拟一个窗口,或者直接调用您的回调,以便在不显示 GUI 元素的情况下运行测试
  • 如果需要,您可以更轻松地移植到不同的 GUI 系统
于 2012-10-16T13:17:41.220 回答