【问题标题】:Unable to bind tkinter slider properly to functions无法将 tkinter 滑块正确绑定到函数
【发布时间】:2020-03-16 10:54:01
【问题描述】:

我正在尝试制作一个简单的城市生成器。我已经成功地制作了指定高度的积木。

另外,我已经能够编写一个使用滑块改变块高度的脚本。

问题

  1. 我不能同时做这两件事。 (我想我可以解决这个问题,因为错误只是在分配之前引用)
  2. 使用水平滑块,我想增加建筑物的数量(可视化为通过减小宽度来增加 x 轴上的条形数量)。但是这段代码不起作用,我的意思是,它甚至没有引发错误。

到目前为止的代码

from tkinter import *
import random

bars = 5
margin = 30
heights= [5, 2, 1, 8, 4]
blocks = []
length = 600
breadth = 360

def draw():
    aligner = margin
    width = (breadth - margin*2)/bars
    for height in heights :
        block = {"height" : height }
        block['rect'] = canvas.create_rectangle(aligner,550-50*height,aligner+width,550, fill="green")
        block['color'] = 'green'
        blocks.append(block)
        aligner += width
    root.update()


def wid(e):
    bars = int(e)
    blocks = []
    heights = []
    for i in range(bars):
        h = random.random()*10
        heights.append(h)
    draw()

def h_rand(e):
    factor = e
    heights = [i * factor for i in heights]
    draw()

root = Tk()


width = 60
aligner = 30

slider_y = Scale(root, from_=1 , to=8, bg="blue",command = h_rand)
slider_y.pack(side=LEFT)

canvas = Canvas(root,height=length,width=breadth)
canvas.pack()

for height in heights :
    block = {"height" : height }
    block['rect'] = canvas.create_rectangle(aligner,550-50*height,aligner+width,550, fill="green")
    block['color'] = 'green'
    blocks.append(block)
    aligner += width


slider_x = Scale(root, from_=50 , to=200, orient = HORIZONTAL, bg="blue",command = wid)
slider_x.pack(side=TOP)

root.mainloop()

我很抱歉问题的“描述性格式不那么明确”(很高兴在 cmets 中提供更多详细信息)。这让我困扰了一段时间,我很沮丧。

【问题讨论】:

  • Hmmmm,你设置了一个变量width和一个函数也叫width
  • @jizhihaoSAMA 我认为这不会引发任何错误,因为命令总是将函数作为属性而不是变量。无论如何,我确实改变了它,但是,仍然没有运气!
  • 由于我真的不知道你想做什么,你可以把draw()函数改成draw(bars)。并且在你的函数wid(e)中把draw()改成draw(bars) .拖动滑块时会发生一些变化。
  • @jizhihaoSAMA 它已经开始缩小以前的酒吧但没有添加新的酒吧,但感谢您帮助我前进。请告诉您是否也有解决方案
  • @jizhihaoSAMA(我知道写这个不好,但这是发自内心的)谢谢兄弟,你帮了我很多。

标签: python user-interface tkinter tkinter-canvas


【解决方案1】:

问题在于wid 中的heights 是一个局部变量。您正在更改函数内部的值,但全局变量保持不变。

您要么需要在函数内将heights 声明为全局变量,要么使用全局变量而不用新列表替换它。

要将其清除为全局,请在正在修改的函数顶部添加global heights

def wid(e):
    global heights, blocks
    ...

您可以使用列表的clear 方法来删​​除内容,而无需重置变量本身。为此,请将heights = [] 替换为heights.clear()blocks 也一样:

def wid(e):
    bars = int(e)
    print("bars:", bars)
    blocks.clear()
    heights.clear()
    ...

您还有一个问题,即在创建新画布项目之前没有删除旧画布项目。您的 draw 函数需要销毁旧元素。你可以通过canvas.delete("all") 做到这一点。

【讨论】:

  • 我在使用全局变量实现它时遇到了问题,现在我知道为什么了。通过将整个代码重新格式化为类并将属性引用为该类的特定实例来解决它。 (这种方式现在多态问题)。我也认识到有关 canvas.delete() 的错误。还是谢谢!........当我解决了我发布的问题后,我没有经验,你能指导我吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-12
  • 2019-07-10
  • 2018-04-21
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
  • 1970-01-01
相关资源
最近更新 更多