0

さて、私が抱えている問題は、押された特定のボタンを参照する方法がわからないことです。私はゲームをやっています。使用者がボタンをクリックすると、それがどの X 座標と Y 座標を持っているか知りたいです。したがって、ボタンのグリッドがあり、1 つをクリックすると、座標が必要になり、そのボタンの色が変更されます。:)

問題: グリッドでどのボタンが押されたかがわかります。

前もって感謝します!

def matris():
    for i in range(5):
            newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i: function(i))
            newButton.grid(row = i, column = 0)

    for i in range(5):
            newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i + 5: function(i))
            newButton.grid(row = i, column = 1)

    for i in range(5):
            newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i + 10: function(i))
            newButton.grid(row = i, column = 2)

    for i in range(5):
            newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i + 15: function(i))
            newButton.grid(row = i, column = 3)

    for i in range(5):
            newButton = Button(app, width = 4, height = 2, bg = "blue",command = lambda i=i + 20: function(i))
            newButton.grid(row = i, column = 4)


def function(i):
    if button 23 was clicked.changeColor to e.g "blue"
4

3 に答える 3

1

すべてのコメントと編集を読んだ後、あなたが本当に知りたいのは「どのボタンがクリックされたか?」ということのようです。複数のボタンに同じコマンドを使用する場合。

これを行う最も簡単な方法は、ウィジェットに関連付けられたコマンドにある種の一意の識別子を渡すことです。最も簡単な方法は、ウィジェット自体への参照を渡すことですが、これには 2 段階のプロセスが必要です。

例えば:

this_button = Button(...)
this_button.configure(command=lambda button=this_button: do_something(button))

def do_something(button):
    print "you clicked this button:", button

functools.partialラムダを理解するのが難しい場合は、 を使用して同じ結果を取得することもできます。

this_button.configure(command=functools.partial(do_something, this_button)

2 つのステップではなく 1 つのステップでボタンを作成したい場合は、ボタンを識別する何らかの方法が必要です。私にとって、最も簡単な方法は辞書を使うことです。たとえば、ボタンの行と列を作成する場合は、次のようにすることができます。

button = {}
for r in range(10):
    for c in range(10):
        button[r,c] = Button(..., command=lambda row=r, column=c: do_something(row, ccolumn))

def do_something(row, column):
    print "you clicked button", button[row,column]
于 2012-10-10T21:12:29.343 に答える
0

後でそのボタンを変更する場合は、各ボタンへの参照を保持する必要があります。番号付けスキームは連続しているため、リストを使用できます。

newButton = Button(...)
buttons.append(newButton)
...
def function(i):
    widget = buttons[i-1] # -1, because list indexes are zero-based
    if i == 23:
        widget.configure(background="blue")

ボタンのグリッドを作成していて、それ以外の点ではボタンが同一である場合は、次のようなより単純な構造を検討することをお勧めします。

for row in range(5):
    for column in range(5):
        ...

5 行 5 列を作成していることはすぐにわかりますが、元のコードでは同じ結論に達するまでに数秒の調査が必要です。

于 2012-10-02T19:27:30.607 に答える
-1

command引数を使用する代わりに、bindメソッドを使用してのコールバックを設定します<Button-1>。Tkinterがコールバックを呼び出すと、イベントを発生させたウィジェットを含むイベントオブジェクトが渡されます。

from Tkinter import *

def buttonClicked(e):
    e.widget["bg"] = "red"

root = Tk()

for x in range(5):
    for y in range(5):
        newButton = Button(root, width=10, height=2, bg="blue")
        newButton.bind("<Button-1>", buttonClicked)
        newButton.grid(row=y, column=x)

root.mainloop()

編集:グリッド内のボタンの位置に応じて、ボタンの扱いを変えたいとします。これを行う最も簡単な方法は、グローバルディクショナリを使用して各ボタンをその座標に関連付けることです。

from Tkinter import *

coords = {}

def buttonClicked(e):
    x,y = coords[e.widget]
    print "{},{} clicked".format(x,y)
    if x == 4 and y == 3:
        e.widget["bg"] = "red"

root = Tk()

for x in range(5):
    for y in range(5):
        newButton = Button(root, width=10, height=2, bg="blue")
        newButton.bind("<Button-1>", buttonClicked)
        newButton.grid(row=y, column=x)
        coords[newButton] = (x,y)

root.mainloop()

ただし、一般的に、グローバルスコープで変数を使用することはお勧めできません。グリッドベースのすべてのコードを1つのクラスにグループ化することは価値があるかもしれません。そのため、その詳細がプログラムの残りの部分に漏れることはありません。

from Tkinter import *

class ButtonGrid:
    def __init__(self, root):
        self.coords = {}
        for x in range(5):
            for y in range(5):
                newButton = Button(root, width=10, height=2, bg="blue")
                newButton.bind("<Button-1>", self.buttonClicked)
                newButton.grid(row=y, column=x)
                self.coords[newButton] = (x,y)

    def buttonClicked(self, e):
        x,y = self.coords[e.widget]
        print "{},{} clicked".format(x,y)
        if x == 4 and y == 3:
            e.widget["bg"] = "red"

root = Tk()
b = ButtonGrid(root)
root.mainloop()

オブジェクト指向よりも機能を好む場合は、別の方法があります。command元のコードで行ったようにオプションを使用しますが、関数を使用して、functools.partial関数に渡す必要のある変数を事前に指定します。

from Tkinter import *
import functools

def buttonClicked(widget, x, y):
    print "{},{} clicked".format(x,y)
    if x == 4 and y == 3:
        widget["bg"] = "red"

root = Tk()

for x in range(5):
    for y in range(5):
        newButton = Button(root, width=10, height=2, bg="blue")
        newButton["command"] = functools.partial(buttonClicked, newButton, x, y) 
        newButton.grid(row=y, column=x)

root.mainloop()
于 2012-10-02T16:34:58.220 に答える