2014-06-05 6 views
0

그래서 MyButton과 MyLabel이라는 하위 클래스가있는 Application 클래스가 있습니다. 응용 프로그램도 있습니다Super() python이 서브 클래스 tkinter에서 작동하지 않습니다.

self.backgroundcolor = 'orange' 
self.textcolor = 'black' 

하위 클래스 MyButton 및 MyLabel에서이 두 변수를 사용하고 싶습니다. 그래서,

class MyButton(Button): 
    def __init__(self, *args, **kwargs): 
     Button.__init__(self, *args, **kwargs) 
     self['bg'] = super(Application, self).backgroundcolor 
     self['fg'] = super(Application, self).textcolor 
     self['relief'] = FLAT 

class MyLabel(Label): 
    def __init__(self, *args, **kwargs): 
     Label.__init__(self, *args, **kwargs) 
     self['fg'] = super(Application, self).textcolor 

을 시도하지만

class Application(Frame): 
    global yearcal 
    def __init__(self, master=None): 
     Frame.__init__(self, master) 
     self.month = 5 
     self.year = 2014 
     self.color_clicked = 'lightskyblue' 
     now = datetime.datetime.now() 
     self.thisyear = now.year 
     self.thismonth = now.month 
     self.today = now.day 
     self.textcolor = 'purple' 
     self.bgcolor = 'gray' 
     self.today_color = 'palegreen1' 
     self.apt_color = 'light coral' 
    MORE STUFF HERE... 

    class MyButton(Button): 
     def __init__(self, *args, **kwargs): 
      Button.__init__(self, *args, **kwargs) 
      self['bg'] = super(Application, self).backgroundcolor 
      self['fg'] = super(Application, self).textcolor 
      self['relief'] = FLAT 

    class MyLabel(Label): 
     def __init__(self, *args, **kwargs): 
      Label.__init__(self, *args, **kwargs) 
      self['fg'] = super(Application, self).textcolor 
+0

'MyButton'은'Button'을 상속받습니다. 'Button'은'Application'에서 상속 받았습니까? –

+0

버튼은 버튼을 만드는 미리 정의 된 tkinter 물건입니다. MyButton은 응용 프로그램의 변수 backgroundcolor 및 textcolor를 기반으로 자동으로 특성을 제공하는 '사용자 지정된'버전입니다. 미안하지만 더 자세한 설명은 할 수 없습니다. 내가 슈퍼 (응용 프로그램, 슈퍼 (버튼, 자기))와 같은 것을해야한다고 말하고 있습니까? 어쩌면 내가 그것을 시도해야합니다. – Kevin

+0

아니요, 작동하지 않았습니다. Button()이 tkinter의 일부이기 때문일 수 있습니다. – Kevin

답변

2

중첩 된 클래스 캔트 액세스의 서브 클래스는 직접 외부 클래스의 속성. 그래서 대신에 일을 : 당신의 type와 "자신"(자기) 통과

class Application(Frame): 
    global yearcal 
    def __init__(self, master=None): 
     Frame.__init__(self, master) 
     self.month = 5 
     self.year = 2014 
     self.color_clicked = 'lightskyblue' 
     now = datetime.datetime.now() 
     self.thisyear = now.year 
     self.thismonth = now.month 
     self.today = now.day 
     self.textcolor = 'purple' 
     self.bgcolor = 'gray' 
     self.today_color = 'palegreen1' 
     self.apt_color = 'light coral' 

     # create button and label and pass the application instance 
     # so that they can reference its attributes and methods 
     self.my_button = MyButton(self) 
     self.my_label = MyLabel(self) 



class MyButton(Button): 
    def __init__(self, app_instance, *args, **kwargs): 
     Button.__init__(self, *args, **kwargs) 

     self['bg'] = app_instance.backgroundcolor 
     self['fg'] = app_instance.textcolor 

     self['relief'] = FLAT 

class MyLabel(Label): 
    def __init__(self, app_instance, *args, **kwargs): 
     Label.__init__(self, *args, **kwargs) 

     self['fg'] = app_instance.textcolor 
0

So I have a class, Application, with 2 subclasses MyButton and MyLabel.

MyButtonMyLabel가 표시되지 않습니다처럼

TypeError: super(type, obj): obj must be an instance or subtype of type 

하지만 내 응용 프로그램 클래스는 보이는 것을 말하는 작동하지 않습니다 Application의 서브 클래스 일 것 super()으로 전화하여 서브 클래스에서 Application에 액세스 할 수 있습니다. 예를 들어

, 만드는 MyLabelApplication

class MyLabel(Application): 
     def __init__(self, *args, **kwargs): 
      ... 
+0

아, 응용 프로그램에 중첩되어 있으면 작동하지 않습니까? 나는 nooby 소리해야하지만, 나는 그것을 몰랐다. – Kevin

+0

이름이 무엇인지 기다려주십시오. 응용 프로그램이 정의되지 않았습니다. – Kevin

+1

예,'MyLabel'이'Application'을 상속한다고 직접 지정해야합니다. 상속은 일부 상황에서만 의미가 있습니다. 예를 들어, 기본 클래스는 다양한 애트리뷰트 및 메소드가있는 'Animal'입니다. 그런 다음이 클래스를 확장하는'Dog' 클래스와'Cat' 클래스가 있습니다. 모든 메소드 (예 :'sleep')는'Animal' 클래스에 정의되어 50 회가 아니라 한 번 정의하면됩니다. –

0

를 호출에서 당신이 super()에 : 당신은 예를 들어, 간접적으로 할 필요가

super(Application, self) 

당신에게 수행해야합니다

super(MyButton, self) 
따라서

오류, obj must be an instance or subtype of type을 :
을은 Application의 인스턴스도 하위 유형도 아닙니다

0

다른 클래스 내에 정의 된 클래스 인 중첩 클래스와 기존 클래스를 확장하여 정의 된 클래스 인이 클래스는 혼동을 일으 킵니다. 파이썬에서

는 (슈퍼 방법의 기반이되는) 클래스 상속 매개 변수로 제공하는 슈퍼 클래스와 클래스를 정의하여 수행됩니다

class Application(Frame): 
    ... #Some class definition 

class MyButton(Application): 
    ... #MyButton is now a subclass of Application. 

그러나 이것은 당신 때문에, 당신이 원하는 아니다 각각 당신의 MyButtonMyLabel 클래스의 Tkinter를 ButtonLabel 클래스의 동작을 상속 (보다는 Application 클래스의 동작을 상속 할.

당신은 중첩 된 클래스를 사용하여 원래의 시도가 표시되지 않습니다 꼭 나쁜 생각 인 것 같습니다. 왜냐하면 클래스의 모든 행동을 한 곳으로 깔끔하게 정리할 것이기 때문입니다. 그러나 그것은 여러분이 원하는 것이 아닌 심각한 단점이 있습니다.

처음에는 중첩 된 클래스에서 인스턴스를 초기화하는 동안 삽입하지 않고 Application 클래스의 인스턴스를 참조 할 수 없습니다.그러나 중첩 된 클래스와 마찬가지로 클래스 속성 인 경우 Application 클래스 네임 스페이스에 정의 된 속성에 액세스 할 수 있습니다. 이것은 아마도 그래서 여기 혼동하는 예이다 :

class Application(object): 
    classvar = "Foo" #This is a class level variable 

    class NestedClass(object): 
     #This is now a nested class, accessed using Application.NestedClass 
     def __init__(self, app): 

      #This will fail, classvar doesn't exist in this scope 
      self.var = classvar 

      #This will work if app is an instance of Application 
      #Or if app is the class itself 
      self.var = app.classvar 

      #This will always work, since it references the Application 
      #class directly but it won't capture changes introduced 
      #by an instance of Application, which is what you'll probably do 
      self.var = Application.classvar 

클래스 수준의 동작 범위 지정으로 인해 매우 혼란되고, 중첩 된 클래스는 상기 모든 클래스를 구현에서 얻을 수없는 아무것도 더욱 혼란 모듈 수준.

이런 종류의 요구 사항을 주입하는 가장 좋은 방법은 바로 그 방법으로 수행하는 것입니다. Tkinter 그 자체입니다. Application 인스턴스를 작성한 위젯 인스턴스의 마스터로 넘겨줍니다. 이것은 Marcin의 대답에 나와 있습니다.

관련 문제