首页 > 解决方案 > 如何使用 tkinter 在 python 中随机化按钮位置?

问题描述

我正在尝试创建一个可点击的词云,我开始使用按钮为其应用逻辑。我可以使用正则表达式拆分文本文件的单词并为每个单词创建按钮。但是每个按钮的位置都显示在一个列视图中。如下图所示:

在此处输入图像描述

tkinter 是否有任何功能来随机化这个位置并手动更改按钮,这可以让我看到一个可点击的词云。

这是我的工作解决方案:

# import the 'tkinter' module
import tkinter
# import regular expression
import re

# create a new window
window = tkinter.Tk()
# set the window title
window.title("Commands")
# set the window icon
window.wm_icon

bitmap('Icon.ico')

# initially, the button hasn't been pressed
presses = 0


# a function that changes the text of the label to a location of the word clicked
def locate():
    global presses
    # add code to find the location of the word ---------------
    # update the label text with the new value of 'presses' -----------
    lbl.configure(text=presses)

# create a label to display a message
lbl = tkinter.Label(window, text=presses)
lbl.pack()

# looping through the number f words
# create a new button, assign a specific text to each button and provide an argument called 'command'
# which in this case calls a function called 'callback'
with open ('sample.txt','r') as f:
    f_contents = f.read()
    # Removing URLs
    f_contents = re.sub(r'http\S+',"",f_contents)
    # Removing all the punctuations
    f_contents = re.sub(r'[^\w\s]', '', f_contents)
    for word in f_contents.split():
        btn = tkinter.Button(window, text=word, command=locate)
        btn.pack()

# draw the window, and start the 'application'
window.mainloop()

提前致谢。

标签: pythonpython-3.xtkintertkinter-canvasword-cloud

解决方案


您可以使用place几何管理器将小部件放置在精确的坐标处。您可以random.randint用来计算随机坐标。如果您使用画布,则可以使用内置方法find_overlapping来确定是否有任何东西会与计算的位置重叠。

这是一个简单的例子:

import tkinter as tk
import random

words = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]

def place_label(canvas, label):
    '''place a label on a canvas in a random, non-overlapping location'''
    width = label.winfo_reqwidth()
    height = label.winfo_reqheight()

    tries = 0
    while True and tries < 1000:
        tries += 1 # failsafe, to prevent an infinite loop
        x = random.randint(0, 200-width)
        y = random.randint(0, 200-height)
        items = canvas.find_overlapping(x, y, x+width, y+height)
        if len(items) == 0:
            canvas.create_window(x, y, window=label, anchor="nw")
            break

root = tk.Tk()
canvas = tk.Canvas(root, width=200, height=200)
canvas.pack(fill="both", expand=True)

for word in words:
    label = tk.Label(root, text=word)
    place_label(canvas, label)

root.mainloop()

推荐阅读