[英]Python Tkinter Button Widget Won't Move
I've been working on a tic-tac-toe projejct, and I am planning on creating 9 button widgets with a picture on each one of them. 我一直在做井字游戏项目,并且我计划创建9个按钮小部件,每个小部件上都带有图片。 I want to move them so they'll be 3 on a line and 3 in a row. 我想移动它们,以便它们在一行中是3,在一行中是3。 Here's my code: 这是我的代码:
#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()
Please note that there's this line: 请注意,有这行:
#self.b.place(bordermode = OUTSIDE, x = x_pixels, y = y_pixels)
In the code, which I've put as a note, which is basically the line that's supposed to move the buttons. 在代码中,我已将其作为注释,基本上是应该移动按钮的行。 If you run the code, it'll simply put all the buttons one under another in a row, 9 of them. 如果您运行代码,它将简单地将所有按钮连续9个放在一个按钮的下面。 After the self.b.place() line, they all simply disappear. 在self.b.place()行之后,它们都消失了。 Maybe they moved somewhere too far, maybe not, but I assume the place() isn't working, and I've had trouble figuring why. 也许他们移得太远了,也许没有,但是我认为place()无法正常工作,而且我很难弄清楚为什么。
Thanks in advance. 提前致谢。
Your best bet would likely be to use the grid
geometry manager, see: http://www.effbot.org/tkinterbook/grid.htm 最好的选择是使用grid
几何管理器,请参见: http : //www.effbot.org/tkinterbook/grid.htm
Instead of creating a GameButton class
, I would put something like this in my GUI class
: 与其创建GameButton class
,不如在GUI class
放置以下内容:
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
This will neatly grid
your buttons into a 3x3 grid. 这会将您的按钮整齐地grid
化为3x3网格。
The button_list
allows you to keep a reference to the button objects, making them easier to access later on, you can use button_list[some_index].grid_info()["row"/"column"]
to obtain the row or column that a button is gridded in, for example. button_list
允许您保留对按钮对象的引用,使它们以后更易于访问,您可以使用button_list[some_index].grid_info()["row"/"column"]
来获取按钮的行或列例如被网格化。
This is the standard way to create a set of similar widgets, and evades the problem of generating and maintaining names with lots of identical repeated code, without needing to create a new class for it. 这是创建一组相似小部件的标准方法,并且避免了使用大量相同的重复代码生成和维护名称的问题,而无需为其创建新类。
A word of warning, from effbot: 来自effbot的警告语:
Warning: Never mix grid and pack in the same master window. 警告:切勿在同一主窗口中混合网格和打包。 Tkinter will happily spend the rest of your lifetime trying to negotiate a solution that both managers are happy with. Tkinter会很乐意度过余生,以期寻求双方经理都满意的解决方案。 Instead of waiting, kill the application, and take another look at your code. 不用等待,而杀死应用程序,然后再看一遍您的代码。 A common mistake is to use the wrong parent for some of the widgets. 一个常见的错误是对某些小部件使用错误的父级。
Finally, as @Terry Jan Reedy
said, you don't need a Canvas
for this, likely a Frame
, or just a straightforward Tk()
would be much better. 最后,就像@Terry Jan Reedy
所说的那样,您不需要Canvas
,可能是Frame
,或者简单的Tk()
会更好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.