【问题标题】:Cant figure out how to stop columns and rows from shifting in TkInter GUI无法弄清楚如何阻止列和行在 TkInter GUI 中移动
【发布时间】:2016-03-04 07:41:26
【问题描述】:

所以,我正在为我的 Python 类做一个最终项目,并正在使用 TkInter 为游戏创建一个 GUI。如果您愿意使用按钮在 GUI 上移动,我有一个小“精灵”。我试图弄清楚如何在“精灵”四处移动时停止烦人的行和列的重新调整大小。我也想知道如何检测一个单元格是否被占用。如果我能以某种方式看到网格的网格线,那就太好了,但我认为这是不可能的,所以下一个最好的事情是知道如何永久设置网格的列和行并使其不可更改。如果我不清楚我想要什么,我很抱歉,我脑子里只有几十个想法。

这是我目前的代码

from tkinter import *
from tkinter.constants import *

master= Tk()
master.resizable(width=False, height=False)

#for erasing displayed text when not needed anymore
wordsShowing = 0


#for testing button function with map movement
#url for image is http://files.softicons.com/download/game-icons/minecraft-avatars-icons-by-stefan-kroeber/png/50x50/slime.png if you want to see exactly what im seeing
pic = PhotoImage(file="C:\\Users\\Bill\\Desktop\\Python\\Final\\slime.png")
image = Label(master, image=pic)
image.grid(row=0, column=3, columnspan=1, rowspan=1, padx=0, pady=0)


#button functions (im not sure which buttons we will actually be using but im trying to cover all our bases)
def left():
    while wordsShowing == 1:
        varLabel.grid_remove()
        wordsShowing = 0
    info = image.grid_info()
    move = info["column"]
    stay = info["row"]
    if move > 0:
        image.grid_remove()
        image.grid(row=stay, column=move-1, columnspan=1, rowspan=1, padx=0, pady=0)
    else:
        varLabel = Label(master, text='Sorry, you can not go that direction.')
        varLabel.grid(row=1, column=2, rowspan=4)
        wordsShowing = 1
    global wordsShowing
    global varLabel

def right():
    while wordsShowing == 1:
        varLabel.grid_remove()
        wordsShowing = 0
    info = image.grid_info()
    move = info["column"]
    stay = info["row"]
    if move < 4:
        image.grid_remove()
        image.grid(row=stay, column=move+1, columnspan=1, rowspan=1, padx=0, pady=0)
    else:
        varLabel = Label(master, text='Sorry, you can not go that direction.')
        varLabel.grid(row=1, column=2, rowspan=4)
        wordsShowing = 1
    global wordsShowing
    global varLabel


def down():
    while wordsShowing == 1:
        varLabel.grid_remove()
        wordsShowing = 0
    info = image.grid_info()
    move = info["row"]
    stay = info["column"]
    if move < 5:
        image.grid_remove()
        image.grid(row=move+1, column=stay, columnspan=1, rowspan=1, padx=0, pady=0)
    else:
        varLabel = Label(master, text='Sorry, you can not go that direction.')
        varLabel.grid(row=1, column=2, rowspan=4)
        wordsShowing = 1
    global wordsShowing
    global varLabel


def up():
    while wordsShowing == 1:
        varLabel.grid_remove()
    wordsShowing = 0
    info = image.grid_info()
    move = info["row"]
    stay = info["column"]
    if move > 0:
        image.grid_remove()
        image.grid(row=move-1, column=stay, columnspan=1, rowspan=1, padx=0, pady=0)
    else:
        varLabel = Label(master, text='Sorry, you can not go that direction.')
        varLabel.grid(row=1, column=2, rowspan=4)
        wordsShowing = 1
    global wordsShowing
    global varLabel


def submit():
    var = command.get()
    varLabel = Label(master, text=var)
    varLabel.grid(row=1, column=2, rowspan=4)
    wordsShowing = 1
    global wordsShowing
    global varLabel


#created widgets
label1 = Label(master, text="Enter a command:")
command = Entry(master, width=80)
leftButton = Button(master, text="<", command=left)
rightButton = Button(master, text=">", command=right)
downButton = Button(master, text="v", command=down)
upButton = Button(master, text="^", command=up)
submitButton = Button(master, text="SUBMIT", command=submit)

#display widgets
label1.grid(row=5, column=1, sticky=E)
command.grid(row=5, column=2)
leftButton.grid(row=2, column=2, sticky=E, padx=3)
rightButton.grid(row=2, column=3)
downButton.grid(row=3, column=3, sticky=W)
upButton.grid(row=1, column=3, sticky=W)
submitButton.grid(row=5, column=3, pady=5, padx=5)

您能提供的任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 我假设您是故意使用 Tkinter?我的意思是,你正在制作游戏,你首先看的是 Pygame 对吧?
  • 您的代码有点长,我认为所有这些代码都与您的问题无关。请参阅:minimal reproducible example。此外,要绘制网格,您可能需要检查 canvas.create_line()
  • 另外,你检查过grid_propagate()吗?
  • 除非按钮和精灵混合是游戏固有的一部分,否则我不会将它们混合在同一帧中。如果我确实想要它们在一起,我会使用画布并将按钮放在画布上 infohost.nmt.edu/tcc/help/pubs/tkinter/web/create_window.html 并在画布周围移动精灵。
  • 我想我应该做更多的研究。我不知道 Pygame。 facepalm 抱歉,代码太长了......跨度>

标签: python python-3.x tkinter grid-layout


【解决方案1】:

可以使用函数 .minsize 设置每个网格单元的最小尺寸。如果您设置的最小尺寸总是大于您放入每个单元格的小部件,则单元格不会在您移动物体时改变大小。请参阅此手册页:http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/grid-config.html

【讨论】:

    【解决方案2】:

    如果您使用的是 Python 3.X,那么您的代码会出现一些问题。

    • 第一个问题是您尝试使用.png 文件,而PhotoImage 类只接受.gif.pgm.ppm 文件。你可以在PhotoImage Doc阅读文档。
    • 下一个问题是警告,您在函数末尾将变量设置为global。 python的工作方式是,如果一个变量在函数内声明它是局部的,所以你通常做的是在函数的开头告诉它,好的,这个变量是全局的,然后继续修改它。如果不是,您无法确定您正在处理的变量是您想要的全局变量。
    • 对于网格大小调整,最好的选择是将按钮放在网格内,在网格内,以便它们的大小与主网格中单元格的大小无关。并且最好在框架上显示东西而不是直接在 master 上。我会将您的代码更改为类似的内容(并将 Labels 和 Frames 从函数替换为在 master 上构造以在 gridFrame 上构造):

      WIDTH = 200
      HEIGHT = 200
      
      master= Tk()
      master.resizable(width=False, height=False)
      gridFrame = Frame(master, width=WIDTH, height=HEIGHT)
      gridFrame.grid()
      
      # Your function code goes here
      
      buttonGrid = Frame(gridFrame)
      buttonGrid.grid(row=4, column=3, sticky=N)
      # created widgets
      label1 = Label(gridFrame, text="Enter a command:")
      command = Entry(gridFrame, width=80)
      leftButton = Button(buttonGrid, text="<", command=left)
      rightButton = Button(buttonGrid, text=">", command=right)
      downButton = Button(buttonGrid, text="v", command=down)
      upButton = Button(buttonGrid, text="^", command=up)
      submitButton = Button(gridFrame, text="SUBMIT", command=submit)
      
      # display widgets
      label1.grid(row=5, column=1, sticky=E)
      command.grid(row=5, column=2)
      leftButton.grid(row=1, column=0, sticky=E)
      rightButton.grid(row=1, column=2, sticky=W)
      downButton.grid(row=2, column=1, sticky=N)
      upButton.grid(row=0, column=1, sticky=S)
      submitButton.grid(row=5, column=3, pady=5, padx=5)
      
    • 通过简单地拥有一个最初为空的矩阵,当您将某些东西放在某个行和列时,将矩阵的这些索引更改为True,然后只需检查位置[i][j]的矩阵,看看它是否被占用

    希望有所帮助。

    【讨论】:

    • 对不起,我忘了补充一点,当你在 tkinter 中定位网格时,会保持从 0 开始的编程索引,所以如果你希望图像不超出Enter command: 标签,您可以将其索引列设置为 0 而不是 1。
    • tk 8.6,包含在 Windows 上的 3.4 和 3.5 中,显示 .png。我相信,链接的文档已有十年左右的历史了。
    • 约束依然存在,我用python 3.5试了一下。
    • 我在 Windows 环境中,不能 100% 确定,但由于文件格式的原因,这可能只是 Windows 的问题。
    • 你指的是什么约束?我已经在 tk8.6 中使用并显示了 .png 文件。
    猜你喜欢
    • 2014-12-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多