2016-06-18 14 views
3

Pythonで単純なタイマーを作成しようとしていて、クラスを使用してユーザーインターフェイスを構築しようとしています。クラスを使用してユーザーインターフェイスを初期化したいと思います。本文の本文では、.gridと.configureメソッドを使って属性を追加したいと思います。しかし、私がこれをしようとすると、エラー: 'statInter'オブジェクトには属性 'tk'が表示されません。エラーの説明 - 'statInter'オブジェクトに 'tk'属性がありません

私はプログラミングの初心者ですが、エラーが正しく理解されれば、.gridやその他のボタンメソッドはstatInter(つまり静的インターフェイス)クラスに継承されないためです。これは正しいです?このエラーを解決するにはどうすればよいですか?私はButtonクラスとTkクラスのプロパティを継承していましたが、後のケースでは無限ループ、つまり最大再帰深度を超えています。あなたは(どちらかButtonまたはEntry)から継承しているクラスからのコンストラクタのいずれかを呼び出すことはありませんので、あなたの助け

#This is a simple timer version 

from tkinter import * 

window = Tk() 
window.title('Tea timer') 
window.minsize(300,100) 
window.resizable(0,0) 

class statInter(Button,Entry): 

    def __init__(self, posx, posy): 
     self.posx = posx # So the variables inside the class are defined broadly 
     self.posy = posy 

    def button(self): 
     Button(window).grid(row=self.posx, column=self.posy) 

    def field(self): 
     Entry(window, width=5) 

sth = statInter(1,2) 
sth.grid(row=1, column = 2) 

window.mainloop() 

答えて

4

問題があり、一般的にはPythonで暗黙的に発生しませんその基底クラスを初期化しませんあなたの派生StatInterクラス(PEP 8 - Style Guide for Python Codeで提案されているようにCamelCasingクラス名)(それは、C++と言うの場合のように)。

StatInter.__init__()メソッド内でそれを行うには、それを含むparentウィジェットを知る必要があります(最上位ウィンドウを除くすべてのウィジェットは階層に含まれています)。派生クラスのコンストラクタに渡されるので、各基本クラスコンストラクタに渡すことができます。

まだ別の問題は発生していませんが、間もなく解決される可能性があります。これを避けるには、button()field()の基本クラスメソッドを明示的に呼び出すときに、明示的にselfを渡す必要があります。

from tkinter import * 

window = Tk() 
window.title('Tea timer') 
window.minsize(300,100) 
window.resizable(0,0) 

class StatInter(Button, Entry): 

    def __init__(self, parent, posx, posy): # Added parent argument 
     Button.__init__(self, parent) # Explicit call to base class 
     Entry.__init__(self, parent) # Explicit call to base class 
     self.posx = posx # So the variables inside the class are defined broadly 
     self.posy = posy 

    def button(self): 
     Button.grid(self, row=self.posx, column=self.posy) # Add self 

    def field(self): 
     Entry.config(self, width=5) # Add self 

sth = StatInter(window, 1, 2) # Add parent argument to call 
sth.grid(row=1, column=2) 

window.mainloop() 
+0

私はOPが_either_ 'Button'と' Entry'ではなく、両方を作成するために '' Button'とEntry'、_or_使用組成物から継承したいが疑われるが、これは、良い答えです。 –

+0

@ブライアン:ありがとう。もちろん、「is-a」対「has-a」問題があることは間違いありません。私は即時の問題を解決するために十分に答えようとしていたので、OPは彼らの開発を続けることができました。また、Pythonで複数の継承を行う際の潜在的な将来の落とし穴を指摘しました。 – martineau

1

このエラーが発生した理由は

おかげです。

あなたがあるためにあなたの__init__を変更した場合:

def __init__(self, posx, posy): 
    Button.__init__(self) 
    self.posx = posx # So the variables inside the class are defined broadly 
    self.posy = posy 

次に、あなたが以前持ったエラーを取得することはできません、と小さなウィンドウがポップアップ表示されます。新しい__init__では、Buttonのコンストラクタを明示的に呼び出します。

Javaと他の言語とは異なり、superコンストラクタはデフォルトで呼び出されません。私は、他のtkinterクラスから継承している各クラスにtkフィールドが必要であると仮定します。親コンストラクタを呼び出すと、このフィールドが作成されます。ただし、親コンストラクタを呼び出さないと、これは確立されたフィールドではなく、記述したエラー( 'statInter'オブジェクトには属性 'tk'がありません)が表示されます。

HTH!

関連する問題