文件不会在 GUI 程序中读取,仅在 shell

Files won't be read in GUI program, only in shell

大家好,我这里有一段冗长的代码需要帮助, 具体来说:我的最终过程是创建词云的作业,但我什至还没有开始。截至目前,我已经能够创建创建频率累加器的功能和我的第一个 GUI 平台。

当 运行 程序时,gui 要求用户输入他们程序的文件名。但是,您可以输入乱码甚至留空,单击转换文件按钮,它仍然会打开 Shell 并提示用户输入文本文件名,然后是他们想要在列表中输入的单词数。

我什至不想要第二部分(问多少字),但我不知道用另一种方法为我的频率计数器做这件事。

from graphics import *

##Deals with Frequency Accumulator##
def byFreq(pair):
    return pair[1]

##Function to allow user to upload their own text document##
def FileOpen(userPhrase):
    filename = input("Enter File Name (followed by .txt): ")
    text = open(filename, 'r').read()
    text = text.lower()
    for ch in ('!"#$%&()*+,-./:;<=>?@[\]^_{}~'):
        text = text.replace(ch, " ")  
    words = text.split()

    counts = {}
    for w in words:
        counts[w] = counts.get(w,0) + 1
    n = eval(input("Output how many words?"))

    items = list(counts.items())
    items.sort(key=byFreq, reverse=True)
    for i in range(n):
        word, count = items[i]
        print("{0:<15}{1:>5}".format(word, count))

##This Function allows user to simply press button to see an example##
def Example():
    win = GraphWin("Word Cloud", 600, 600)

    file = open("econometrics.txt", "r", encoding = "utf-8")
    text = file.read()
    text = text.lower()
    for ch in ('!"#$%&()*+,-./:;<=>?@[\]^_{}~'):
        text = text.replace(ch, " ")  
    words = text.split()

    counts = {}
    for w in words:
        counts[w] = counts.get(w,0) + 1
    n = eval(input("Output how many words?"))

    items = list(counts.items())
    items.sort(key=byFreq, reverse=True)
    for i in range(n):
        word, count = items[i]
        print("{0:<15}{1:>5}".format(word, count))
#########################################################################
##Gold Boxes##
def boxes(gwin, pt1, pt2, words):

    button = Rectangle(pt1, pt2)
    button.setFill("gold")
    button.draw(gwin)

    #Middle of the box coordinates
    labelx = (pt1.getX() + pt2.getX())/2.0
    labely = (pt1.getY() + pt2.getY())/2.0

    #Labels
    label = Text(Point(labelx,labely),words)
    label.setFill("black")
    label.draw(gwin)

####GUI function#####  
def main():

    #Creates the actual GUI
    win = GraphWin("Word Cloud Prompt", 600, 600)

    #Box which user types into:
    inputBox = Entry(Point(300,150),50)
    inputBox.draw(win)

    #Gold Boxes at Top
    boxes(win, Point(220,300), Point(370,350), "Transform Text File")
    boxes(win, Point(220,400), Point(370,450), "Example text file")

    #Tells user what to do
    prompt = Text(Point(300,25),"Welcome to the Word Cloud program!")
    prompt.draw(win)

    prompt = Text(Point(300,125),"Enter your textfile name")
    prompt.draw(win)

    prompt = Text(Point(300,180),"Want to see our own file into a Word Cloud? Click below")
    prompt.draw(win)

    #display answer
    display = Text(Point(300, 500),"")
    display.draw(win)

    #User Clicks a box:
    pt = win.getMouse()

    #Store user info
    userPhrase = inputBox.getText()
    key = inputBox.getText()

    #Incase a button isn't clicked
    output = "No button was clicked, Please restart program"


    #Clicking the Transform Text File Button
    if pt.getY() >= 300 and pt.getY() <= 350:
        if pt.getX() >= 220 and pt.getX() <= 370:
            output = FileOpen(userPhrase)

    #Clicking the Example Text File Button
    if pt.getY() >= 400 and pt.getY() <= 450:
        if pt.getX() >= 220 and pt.getX() <= 370:
            output = Example()

    #State Answer
    display.setText(output)
    display.setFill("purple3")
    display.setStyle("bold")

    prompt.setText("Thank You! Click anywhere to close!")
    prompt.setFill("red")

    #closing program
    pt = win.getMouse()
    win.close()
main()

(编者注:为了便于阅读,我修改了一些格式,但功能将完全相同)

def FileOpen(userPhrase):
    """FileOpen allows users to upload their own text document."""

    filename = input("Enter File Name (followed by .txt): ")
    text = open(filename, 'r').read()
    text = text.lower()
    for ch in ('!"#$%&()*+,-./:;<=>?@[\]^_{}~'):
        text = text.replace(ch, " ")
    words = text.split()

    counts = {}
    for w in words:
        counts[w] = counts.get(w, 0) + 1
    n = eval(input("Output how many words?"))

    items = list(counts.items())
    items.sort(key=byFreq, reverse=True)
    for i in range(n):
        word, count = items[i]
        print("{0:<15}{1:>5}".format(word, count))

这是我们关心的功能。您使用来自 gui 文本输入字段的参数 userPhrase 调用它,但是您永远不会 use userPhrase 在函数的任何地方。考虑一下:

def file_open(userPhrase=None):
    # file_open is lowercase and snake_case for PEP8
    # userPhrase=None to make it an optional argument

    filename = userPhrase if userPhrase is not None else \
               input("Enter file name (including extension): ")
    ...

然后,如果您希望 file_open 提示输入文件名(如果未提供文件名),则必须以不同的方式调用它。

def main():

    ...

    if 300 <= pt.getY() <= 350 and 220 <= pt.getX() <= 370:
        # you can chain conditionals as above. It makes it much easier to read!
        # `a <= N <= b` is easily read as `N is between a and b`

        userPhrase = inputBox.getText()
        if userPhrase.strip():  # if there's something there
            file_open(userPhrase)
        else:
            file_open()