简体   繁体   English

Python:如何在消息框中获取输入框?

[英]Python: How to get an entry box within a message box?

I just realised I hadn't asked the user for their name at the start of the game. 我刚刚意识到我没有在游戏开始时询问用户他们的名字。 So I tried this code: 所以我尝试了这段代码:

 Label(root, text="What is you name?").grid(row=0, column=0)
 e1 = self.Entry(root)
 e1.self.grid(row = 0, column=1)

But its not working. 但它不起作用。

How do I get a message box to pop up in the start of the game saying "Welcome to Math bubbles, what is your name?" 如何在游戏开头弹出一个消息框,说“欢迎来到数学泡泡,你叫什么名字?” The user then types in their name and presses ok. 然后用户输入他们的名字并按下确定。 Another message box will pop up saying "Hello _ , press the start button to begin". 弹出另一个消息框,说“Hello _ ,按开始按钮开始”。 I would like to save the users name so that in the Winner message box I could display their name as well 我想保存用户名,以便在Winner消息框中我也可以显示他们的名字

You can use the tkinter.simpledialog function askstring . 您可以使用tkinter.simpledialog函数askstring

from tkinter.simpledialog import askstring
from tkinter.messagebox import showinfo
name = askstring('Name', 'What is your name?')
showinfo('Hello!', 'Hi, {}'.format(name))

您可以创建一个对话框作为modal对话框,然后放入一个输入框和一些按钮来处理它们内部的自定义对话框消息并显示它。

There are no messageboxes that have an entry. 没有包含条目的消息框。 As their name suggests, messageboxes are meant to show messages, not receive input or act like mini GUI's. 顾名思义,消息框旨在显示消息,而不是接收输入或表现为迷你GUI。

Nevertheless, it is quite possible to do what you want. 不过,很有可能做你想做的事。 There are many ways to do it as well. 有很多方法可以做到这一点。 I think the best would be like this: 我认为最好的是这样的:

from tkinter import *
import random
from tkinter.messagebox import showinfo

class BubbleFrame:
    ##############################################
    def __init__(self, root, name):
        self.name = name
    ###############################################
        root.title("Math Bubbles")
        self.bubbles = {}
        self.score = 0
        Button(root, text="Start", width=8, command=self.initialize_bubbles).pack()
        Button(root, text="Quit", width=8, command=quit).pack()
        self.canvas = Canvas(root, width=800, height=650, bg='#afeeee')
        self.canvas.create_text(400, 30, fill="darkblue", font="Times 20 italic bold", text="Click the bubbles that are multiples of two.")
        self.current_score = self.canvas.create_text(200, 60, fill="darkblue", font="Times 15 italic bold", text="Your score is: 0")
        self.canvas.pack()

    def initialize_bubbles(self):
        for each_no in range(1, 21):
            xval = random.randint(5, 765)
            yval = random.randint(5, 615)
            oval_id = self.canvas.create_oval(xval, yval, xval + 30, yval + 30,fill="#00ffff", outline="#00bfff", width=5, tags="bubble")
            text_id = self.canvas.create_text(xval + 15, yval + 15, text=each_no, tags="bubble")
            self.canvas.tag_bind("bubble", "<Button-1>", lambda x: self.click(x))
            self.bubbles[oval_id] = (xval, yval, 0, 0, each_no, text_id)

    def click(self, event):
        if self.canvas.find_withtag(CURRENT):
            item_uid = event.widget.find_closest(event.x, event.y)[0]
            is_even = False
            try:
                self.bubbles[item_uid]
            except KeyError:
                for key, value in self.bubbles.iteritems():
                    if item_uid == value[5]:
                        if value[4] % 2 == 0:
                            is_even = True
                        self.canvas.delete(key)
                        self.canvas.delete(item_uid)
            else:
                if self.bubbles[item_uid][4] % 2 == 0:
                    is_even = True
                self.canvas.delete(item_uid)
                self.canvas.delete(self.bubbles[item_uid][5])
            if is_even:
                self.score += 1
            else:
                self.score -= 1

            if self.score == 10:
                #########################################
                showinfo("Winner", "You won %s!" % self.name)
                #########################################

        self.canvas.delete(self.current_score)
        self.current_score = self.canvas.create_text(200, 60, fill="darkblue", font="Times 15 italic bold", text="Your score is: %s"%self.score)

    def loop(self, root):
        for oval_id, (x, y, dx, dy, each_no, text_id) in self.bubbles.items():
            dx += random.randint(-1, 1)
            dy += random.randint(-1, 1)
            dx, dy = max(-5, min(dx, 5)), max(-5, min(dy, 5))
            if not 0 < x < 770:
                dx = -dx
            if not 0 < y < 620:
                dy = -dy
            self.canvas.move(oval_id, dx, dy)
            self.canvas.move(text_id, dx, dy)
            self.bubbles[oval_id] = (x + dx, y + dy, dx, dy, each_no, text_id)
        root.after(100, self.loop, root)

if __name__ == "__main__":

    root = Tk()
    ###############################################################
    Label(root, text="Welcome to Math bubbles, what is your name?").pack()
    name = Entry(root)
    name.pack()
    def submit(name, root):
        root.destroy()
        root = Tk()
        Label(root, text="Hello %s, press the Start button to begin.\n" % name).pack()
        BubbleFrame(root, name).loop(root)
    Button(root, text="Ok", command=lambda: submit(name.get(), root)).pack()
    ######################################################################
    root.mainloop()

The code inside the comment boxes is what I changed. 注释框中的代码是我更改的内容。 As you can see, my approach was to create a little GUI at startup that asks for a name. 正如您所看到的,我的方法是在启动时创建一个GUI,要求提供名称。 Once it gets it, it sends it to the main application and self-destructs. 一旦它获得它,它将它发送到主应用程序并自我毁灭。

Furthermore, adding the argument name to the __init__ method of BubbleFrame means that now I can do: 此外,将参数name添加到BubbleFrame__init__方法意味着现在我可以这样做:

 self.name = name

and have the user's name as an attribute of BubbleFrame . 并将用户的名称作为BubbleFrame的属性。 Also, note that I did not use a Toplevel window. 另请注意,我没有使用Toplevel窗口。 This is because, if I launched a Toplevel at startup, I would also generate a blank main window, and that looks bad. 这是因为,如果我在启动时启动了Toplevel ,我还会生成一个空白的主窗口,这看起来很糟糕。 This approach is clean and the closest to what you want. 这种方法很干净,最接近你想要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM