【问题标题】:Put histogram in tkinter frame将直方图放在 tkinter 帧中
【发布时间】:2014-08-10 18:19:51
【问题描述】:

我正在尝试将 2 个 Tkinter 程序放在一起。从用户输入的 URL 中获取每个字母的所有出现次数,并在文本框中显示每个字母的计数。另一个是创建直方图的turtle 模块。我希望每个字母的出现都显示为直方图,字母的标签在 x 轴上。

这是我的代码:

from tkinter import *
import tkinter.messagebox
import urllib.request
import turtle

counts = 0

def main():
    analyzeFile(url.get())
    list = [counts]
    drawHistogram(list)

def analyzeFile(url):
    try:
        infile = urllib.request.urlopen(url)
        s = str(infile.read().decode()) # Read the content as string from the URL

        counts = countLetters(s.lower())

        infile.close() # Close file
    except ValueError:
        tkinter.messagebox.showwarning("Analyze URL", 
                                    "URL " + url + " does not exist")

def countLetters(s): 
    counts = 26 * [0] # Create and initialize counts
    for ch in s:
        if ch.isalpha():
            counts[ord(ch) - ord('a')] += 1
    return counts

def drawHistogram(list):
    WIDTH = 400
    HEIGHT = 300

    raw_turtle.penup()
    raw_turtle.goto(-WIDTH / 2, -HEIGHT / 2)
    raw_turtle.pendown()
    raw_turtle.forward(WIDTH)

    widthOfBar = WIDTH / len(list)

    for i in range(len(list)):
        height = list[i] * HEIGHT / max(list)
        drawABar(-WIDTH / 2 + i * widthOfBar,
            -HEIGHT / 2, widthOfBar, height)

    raw_turtle.hideturtle()

def drawABar(i, j, widthOfBar, height):
    raw_turtle.penup()
    raw_turtle.goto(i, j)
    raw_turtle.setheading(90)
    raw_turtle.pendown()

    raw_turtle.forward(height)
    raw_turtle.right(90)
    raw_turtle.forward(widthOfBar)
    raw_turtle.right(90)
    raw_turtle.forward(height)

window = Tk()
window.title("Occurrence of Letters in a Histogram from URL")

frame1 = Frame(window)
frame1.pack()

scrollbar = Scrollbar(frame1)
scrollbar.pack(side = RIGHT, fill = Y)

canvas = tkinter.Canvas(frame1, width=450, height=450)
raw_turtle = turtle.RawTurtle(canvas)

scrollbar.config(command = canvas.yview)
canvas.config( yscrollcommand=scrollbar.set)
canvas.pack()

frame2 = Frame(window)
frame2.pack()

Label(frame2, text = "Enter a URL: ").pack(side = LEFT)
url = StringVar()
Entry(frame2, width = 50, textvariable = url).pack(side = LEFT)
Button(frame2, text = "Show Result", command = main).pack(side = LEFT)

window.mainloop()

def main():开始是直方图部分。如何组合这些以使直方图显示在文本框的位置?提前感谢您的任何意见!

编辑:

【问题讨论】:

  • 您是否有特定的原因要使用海龟而不是在 Tkinter 画布上绘制矩形?
  • 这是一个家庭作业问题,它声明使用乌龟。我的编辑包括它应该是什么样子的屏幕截图。

标签: python tkinter histogram


【解决方案1】:

您可以使用RawTurtle(有关详细信息,请参阅this 主题)。所以,在你的代码中定义raw_turtle

canvas = tkinter.Canvas(frame1, width=450, height=450)
raw_turtle = turtle.RawTurtle(canvas)

并将其用于直方图。完整代码如下所示:

from tkinter import *
import tkinter.messagebox
import urllib.request
import turtle


def main():
    counts = analyzeFile(url.get())
    drawHistogram(counts)

def analyzeFile(url):
    try:
        infile = urllib.request.urlopen(url)
        s = str(infile.read().decode()) # Read the content as string from the URL

        counts = countLetters(s.lower())

        infile.close() # Close file
    except ValueError:
        tkinter.messagebox.showwarning("Analyze URL",
            "URL " + url + " does not exist")

    return counts

def countLetters(s):
    counts = 26 * [0] # Create and initialize counts
    for ch in s:
        if ch.isalpha():
            counts[ord(ch) - ord('a')] += 1
    return counts

def drawHistogram(list):

    WIDTH = 400
    HEIGHT = 300

    raw_turtle.penup()
    raw_turtle.goto(-WIDTH / 2, -HEIGHT / 2)
    raw_turtle.pendown()
    raw_turtle.forward(WIDTH)

    widthOfBar = WIDTH / len(list)

    for i in range(len(list)):
        height = list[i] * HEIGHT / max(list)
        drawABar(-WIDTH / 2 + i * widthOfBar,
            -HEIGHT / 2, widthOfBar, height, letter_number=i)

    raw_turtle.hideturtle()

def drawABar(i, j, widthOfBar, height, letter_number):
    alf='abcdefghijklmnopqrstuvwxyz'
    raw_turtle.penup()
    raw_turtle.goto(i+2, j-20)

    #sign letter on histogram
    raw_turtle.write(alf[letter_number])
    raw_turtle.goto(i, j)

    raw_turtle.setheading(90)
    raw_turtle.pendown()


    raw_turtle.forward(height)
    raw_turtle.right(90)
    raw_turtle.forward(widthOfBar)
    raw_turtle.right(90)
    raw_turtle.forward(height)

window = Tk()
window.title("Occurrence of Letters in a Histogram from URL")

frame1 = Frame(window)
frame1.pack()

scrollbar = Scrollbar(frame1)
scrollbar.pack(side = RIGHT, fill = Y)

canvas = tkinter.Canvas(frame1, width=450, height=450)
raw_turtle = turtle.RawTurtle(canvas)

scrollbar.config(command = canvas.yview)
canvas.config( yscrollcommand=scrollbar.set)
canvas.pack()

frame2 = Frame(window)
frame2.pack()

Label(frame2, text = "Enter a URL: ").pack(side = LEFT)
url = StringVar()
Entry(frame2, width = 50, textvariable = url).pack(side = LEFT)
Button(frame2, text = "Show Result", command = main).pack(side = LEFT)

window.mainloop()

This 关于在画布上使用滚动条的主题也可能有用。

编辑
当我运行上面的代码时,我看到了:

【讨论】:

  • 好的,我现在看到画布上的乌龟了,但我怎么看不到LabelEntryButton 小部件?
  • @annabananana7 嗯。当我运行上面的代码时,我看到了所有的机翼。我添加了屏幕截图。
  • 我添加了我的屏幕截图,这就是我所看到的 =\
  • @annabananana7 好的,尝试减小canvas 的大小。例如:canvas = tkinter.Canvas(frame1, width=450, height=450)
  • 谢谢,我现在可以看到所有小部件了。我正在尝试调整我的代码,以便它可以读取 URL 并返回该网站上的字母计数并绘制直方图。我已经将我的代码更新到了目前为止,并附上了它应该是什么样子的屏幕截图
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-18
  • 1970-01-01
  • 2014-09-10
  • 2014-08-17
相关资源
最近更新 更多