2

エントリ値(コードのS1)を取得して、それ自体を値(_attributesディクショナリのSTR)として設定しようとしましたが、機能させることができません。私はこれを最終的なトップループにしたいのですが、プログラミング全般に慣れていないので、これについては一度に一歩ずつ進んでいきます。私はこれを正しい方法で行っていますか、それとも、押されたときにその時点のエントリ値をルックアップしてそれに合わせて実行するボタンを用意する必要がありますか?私はTkinterのためにオンラインで見つけたいくつかのチュートリアルとレッスンを経験しましたが、それでも私が期待するように何かを機能させることができることから何マイルも離れているようです。

#! usr/bin/python27
from Tkinter import *

class Character:

    def __init__(self, **kvargs):
        self._attributes = kvargs

    def set_attributes(self, key, value):
        self._attributes[key] = value
        return

    def get_attributes(self, key):
        return self._attributes.get(key, None)


def attrInput(stat, x, y):
   """Creates a label for entry box"""
   L = Label(B,
             width = 5,
             relief = RIDGE,
             anchor = E,
             text = stat).grid(row = x,
                             column = y)

B = ""
def main():

    Person = Character()

    B = Tk()

    S1 = Entry(B, width = 3)
    S1.grid(row = 0, column = 1)
    S1.bind("<Key>", Person.set_attributes('STR', S1.get()) )
    attrInput("Str: ", 0, 0)

    Button(B, text='Quit', command=B.destroy).grid(row=3, column=0, sticky=W, pady=4)

    B.mainloop()

    print Person.__dict__

if __name__ == '__main__': main()

新しいコード(少なくとも機能しているようですが、必要なものを取得しています)。トップループにするために少し変更する必要がありますが、これが基盤です

class Character:

    def __init__(self, **kvargs):
        self._attribute = kvargs

    def set_attribute(self, key, value):
        self._attribute[key] = value
        return

    def get_attribute(self, key):
        return self._attribute.get(key, None)


class attrAsk:

    def __init__(self, master, Char, attrName, Row, Column):
        self.Char = Char
        self.attrName = attrName
        attrInput(attrName+":", Row, Column)
        self.e = Entry(master, width = 3)
        self.e.grid(row = Row, column = Column+1)
        self.e.bind("<KeyRelease>", self.set_attr)

    def set_attr(self, event):
        self.Char.set_attribute(self.attrName, self.e.get())


def attrInput(stat, x, y):
   """Creates a label for entry box"""
   L = Label(box,
             width = 5,
             relief = RIDGE,
             anchor = E,
             text = stat).grid(row = x,
                               column = y)

Person= Character()


box = Tk()

STRENT = attrAsk(box, Person, "STR", 0, 0)
DEXENT = attrAsk(box, Person, "DEX", 1, 0)
CONENT = attrAsk(box, Person, "CON", 2, 0)
INTENT = attrAsk(box, Person, "INT", 3, 0)
WISENT = attrAsk(box, Person, "WIS", 4, 0)
CHAENT = attrAsk(box, Person, "CHA", 5, 0)

Button(box,
       text='Continue',
       command=box.destroy).grid(columnspan = 2,
                                                       row=8,
                                                       column=0,
                                                       sticky=W,
                                                       pady=4)

box.mainloop()

print Person.__dict__
4

1 に答える 1

6

行を変更します。

S1.bind("<Key>", Person.set_attributes('STR', S1.get()) )

次のようなものに:

def key_pressed(event):
    Person.set_attributes('STR', S1.get())
S1.bind("<KeyRelease>", key_pressed)

元のコードが機能しない理由は2つあります。

  1. bind2番目の引数として関数を取ります。その関数は、イベントが発生したときに呼び出されます。Person.set_attributes('STR', S1.get())ただし、使用する式はすぐに発生します。その式を関数に入れて、キーが押されたときにのみ発生するようにする必要があります。
  2. <Key>これは、キーが最初に押されたときにイベントが発生することを意味しますが、キーが離されたときに発生することをお勧めしますしたがって、新しい文字が追加されました)。したがって、を使用する必要があります<KeyRelease>

もう1つの注意:すべての機能、特にコールバックメソッドをクラスに編成することをお勧めします。例えば:

class Window(object):
    def __init__(self):
        self.person = Character()

        self.B = Tk()

        self.S1 = Entry(B, width = 3)
        self.S1.grid(row = 0, column = 1)

        self.S1.bind("<KeyRelease>", self.key_pressed)
        attrInput("Str: ", 0, 0)

        self.button = Button(B, text='Quit', command=self.B.destroy).grid(row=3, column=0, sticky=W, pady=4)

        self.B.mainloop()

        print self.person.__dict__

    def key_pressed(self, event):
        self.person.set_attributes('STR', self.S1.get())


def main():
    w = Window()


if __name__ == '__main__': main()

この組織の利点はすぐには明らかにならないかもしれませんが、多数のコールバックメソッドがあり、多数のウィジェットを追跡していると、非常に便利になります。

Entryコメントに応じて、forループ内のオブジェクトとLabelオブジェクトの両方をそれぞれ独自の行に作成できます。次に、メソッドは、ここに示すように、渡されるオブジェクトkey_pressedからフィールドと入力テキストを学習できます(試してみてください)。event

class Window(object):
    def __init__(self):
        self.person = Character()

        self.B = Tk()

        self.fields = ["STR", "DEX", "CON", "INT", "WIS", "CHA"]

        self.inputs = {}
        for i, f in enumerate(self.fields):
            self.inputs[f] = Entry(B, width = 3)
            self.inputs[f].grid(row=i, column=1)
            self.inputs[f].bind("<KeyRelease>", self.key_pressed)
            attrInput(f + ":", i, 0)

        self.button = Button(B, text='Quit', command=self.B.destroy).grid(row=7, column=0, sticky=W, pady=4)

        self.B.mainloop()

        print self.person.__dict__

    def key_pressed(self, event):
        field = self.fields[int(event.widget.grid_info()["row"])]
        self.person.set_attributes(field, event.widget.get())
于 2013-01-19T04:52:50.377 に答える