Python Tkinter按钮小部件赢得';别动

Python Tkinter按钮小部件赢得';别动,python,button,tkinter,widget,move,Python,Button,Tkinter,Widget,Move,我一直在做一个tic-tac-toe项目,我计划创建9个按钮小部件,每个小部件上都有一张图片。我想移动它们,使它们在一条线上3个,在一条线上3个。 这是我的密码: #imports: from Tkinter import * from PIL import ImageTk, Image #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~

我一直在做一个tic-tac-toe项目,我计划创建9个按钮小部件,每个小部件上都有一张图片。我想移动它们,使它们在一条线上3个,在一条线上3个。 这是我的密码:

#imports:
from Tkinter import *
from PIL import ImageTk, Image

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#constants
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#classes:
class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
myapp = App()

class GUI:
    def __init__(self):
        self.myapp = myapp
        self.myapp.master.title("tkname")
        self.myapp.master.maxsize(2000, 1200)

    def create_and_pack_canvas(self, game_board_height, game_board_width):
        canvas = Canvas(height = game_board_height, width = game_board_width)
        canvas.pack(expand=1, fill=BOTH)
        return canvas

    def form_game_board(self):
        x = 404
        y = 150
        canvas = self.create_and_pack_canvas(1000, 1000)

        for i in range(3):
            for j in range(3):
                btn = gameButton("")
                btn.create_and_pack(canvas, x, y)
                x += 200
            x = 404
            y += 208

        self.myapp.mainloop()
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class gameButton:
    def __init__(self, picture_param):
        self.picture = ImageTk.PhotoImage(Image.open("somepic"))
        self.picture_height = self.picture.height()
        self.picture_width = self.picture.width()

    def callback(self):
        print 10

    def create_and_pack(self, canvas, x_pixels, y_pixels):
        self.b = Button(myapp, text="Print 10~", command = self.callback, image = self.picture)
        self.b.pack()
        #self.b.place(bordermode = OUTSIDE, x = x_pixels, y = y_pixels)

    def __str__(self):
        pass
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#main
def main():
    gui = GUI()
    gui.form_game_board()

if __name__ == "__main__":
    main()
请注意,有一行:

#self.b.place(bordermode = OUTSIDE, x = x_pixels, y = y_pixels)
在代码中,我把它作为一个注释,它基本上是用来移动按钮的那一行。如果您运行代码,它只需将所有按钮一个接一个地排成一行,其中9个按钮。 在self.b.place()行之后,它们都消失了。 也许他们搬到了太远的地方,也许不是,但我想这个地方()不起作用了,我很难弄清楚原因


提前感谢。

您的最佳选择可能是使用
栅格
几何体管理器,请参阅:

我不想创建GameButton
,而是在我的GUI
中放置类似的内容:

    button_list = []
    list_index_counter = 0
    row_counter = 0
    column_counter = 0
    for num in range(9):
        self.button = tk.Button(canvas,
                                text="Print 10~",
                                command=self.callback,
                                image=self.callback)
        button_list.append(self.button)
        button_list[list_index_counter].grid(row=row_counter, column=column_counter)
        list_index_counter += 1
        if column_counter < (2): # it will hit this twice
            column_counter += 1
        else:                    # then this once, then back to the other one
            row_counter += 1
            column_counter = 0
按钮列表=[]
列表索引计数器=0
行计数器=0
列计数器=0
对于范围(9)中的num:
self.button=tk.button(画布,
text=“打印10~”,
command=self.callback,
image=self.callback)
按钮列表追加(self.button)
按钮列表[列表索引计数器]。网格(行=行计数器,列=列计数器)
列表索引计数器+=1
如果列_计数器<(2):#它将命中此列两次
列计数器+=1
否则:#然后这一次,然后回到另一次
行计数器+=1
列计数器=0
这将整洁地
网格
您的按钮变成3x3网格

按钮列表
允许您保留对按钮对象的引用,以便于以后访问。例如,您可以使用
按钮列表[某些索引].grid\u info()[“行”/“列”]
获取按钮网格化的行或列

这是创建一组类似小部件的标准方法,避免了使用大量相同的重复代码生成和维护名称的问题,而无需为其创建新类

一句来自effbot的警告:

警告:切勿在同一主窗口中混合网格和包装。Tkinter很乐意在你的余生中尝试协商一个双方经理都满意的解决方案。与其等待,不如关闭应用程序,然后重新查看代码。一个常见的错误是对一些小部件使用错误的父级


最后,正如Terry Jan Reedy所说,你不需要一张画布,很可能是一个
框架,或者仅仅是一个简单的
Tk()
就更好了。

如果你使用按钮,你应该在一个框架中为它们设置3 x 3的网格。在其他的井字游戏问题中也有很多这样的例子。不要使用带有按钮的画布。请注意,
gameButton.create_and_pack
中的
canvas
参数未被使用。我强烈建议使用显式的
root=Tk()