在后台更新tkinter窗口

2024-09-18 18:39:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试制作一个python游戏,理想情况下,我需要创建一个简单的tkinter GUI,由两个按钮和一个文本输入组成

游戏的格式目前由多个函数组成,大部分函数从print(something)开始,然后是input(bunch of stuff\nbunch of stuff\n),最后是一系列“if/else”测试,以获取用户的输入并进行另一个操作(通常调用另一个函数)

这就是当前的情况:

        global BatHP
        global HeroDamage
        global Gold
        print("You manage to hit your enemy, inflicting", HeroDamage,"damage!")
        if BatHP - HeroDamage <= 0: #Id Bat dead test
            randnum = random.randint(2,5) #Calculates won Gold
            winsound.PlaySound("GainOr.wav", winsound.SND_ASYNC) #Plays a sound
            print("You have killed the bat, and got", randnum,"Gold!\n")
            Gold += randnum #Gives Gold to Hero
            what_next() #Launches the next function
            BatHP = 5
        else:
            BatHP -= HeroDamage #Damage dealt by Hero is applied
            print("The bat has", BatHP,"HP left!\n")
            enemy_attack() #calls the enemy\attack function

我的问题是,我不知道如何添加文字到我的游戏。。。我尝试了标签,但它没有更新窗口(“打印的东西”应该与“标签”一起使用,但仍然没有出现在窗口中…)。而且,在我所做的工作中,当我按下一个按钮时,窗口就会崩溃

此外,窗口是否会自我更新,比如添加文本(“标签”),是否会显示,或者是否需要window.update。此外,我有一个问题,我不知道在哪里创建按钮。如果我把它们放在我当前的循环系统(更新的循环系统)中,按钮将无限期地创建,但是如果我把它们放在外部,我会得到一个错误,因为来自按钮的命令类似于一个尚未发现的函数

我不知道这是否有道理,但我真的需要帮助。谢谢你的帮助

PS:这是完整的项目,但它是用法语写的(至少对于所说的句子和变量名): https://drive.google.com/file/d/1VSEWdRxDxHxKpdxROWvh54z9hQytYG5J/view?usp=sharing


Tags: ofthe函数文本游戏情况标签按钮
2条回答

这里有一些演示代码,作为你的游戏结构的一个例子。在本例中,屏幕上会清除所有按钮、标签和条目,然后您必须在下一个场景中创建新的按钮、标签和条目。这支持具有不同布局的场景。如果您希望每个场景都有一个按钮、一个标签和一个条目,您可以更改此结构以节省创建小部件的工作量。试着运行这段代码看看它做了什么,然后查看代码和注释以了解它是如何工作的

import tkinter as tk

class Window():
    def __init__(self, master):
        self.master = master
        self.master.geometry('300x300') # Sets the dimensions of the window
        self.dark_room() # Goes to the first scene, which is created by the function dark_room below

    def new_scene(self, scene, frame, *args):
        # This function will act as a directory, erasing the previous buttons and labels and going to the next function
        frame.destroy() # Destroys the previous frame, which holds all buttons, labels, entries, etc
        goto = { # A dictionary with references to all your scenes. Add each new scene function to here
            'dark_room': self.dark_room,
            'light_room': self.light_room,
            'intro': self.intro
        }
        if args:
            text = args[0]
            goto[scene](text)
        else:
            goto[scene]()

    def dark_room(self, text='You wake up in a dark room. There are matches next to you.'):
        frame = tk.Frame(self.master) # Place a frame in the window, and then make labels/buttons on it. It makes it easier to clear them later
        frame.pack()
        label_text = tk.StringVar() # Use a StringVar to make a label that can have its text changed
        label_text.set(text) # Be sure to change text using the .set() command. Don't use label_text = 'some text'
        tk.Label(frame, textvariable=label_text, wraplength=200).pack()
        tk.Button(frame, text='Look for door', command=lambda: self.new_scene('dark_room', frame, "It's too dark to see.")).pack()
        tk.Button(frame, text='Light a match', command=lambda: self.new_scene('light_room', frame)).pack()

    def light_room(self, text='The match lights up the room. What is your name?'):
        frame = tk.Frame(self.master)
        frame.pack()
        tk.Label(frame, text=text, wraplength=200).pack()
        name = tk.StringVar()
        tk.Entry(frame, textvariable=name).pack() # This entry is linked to the StringVar called name. name.get() will give you the contents of entry
        tk.Button(frame, text='Submit', command=lambda: self.new_scene('intro', frame, name.get())).pack() # Notice we use name.get()

    def intro(self, name):
        frame = tk.Frame(self.master)
        frame.pack()
        tk.Label(frame, text='Your name is %s, the fearless adventurer!' % name, wraplength=200).pack()


root = tk.Tk()
Window(root)
root.mainloop()

整个项目太多了,无法仔细查看,但我看到了一些事情

打印不会转到tkinter标签,而是转到控制台。通过将StringVar链接到标签的textvariable参数,可以使用新文本更新tkinter标签。StringVar的值可以使用其set()方法更改

text = StringVar()
label = Label(parent, textvariable=text)
label.pack()
text.set('Hello world!')

您有一个while True循环,末尾有一个update(),还有一个mainloop()。你应该选择一个或另一个,因为它们完成了几乎相同的事情。此外,程序首先遇到的任何一个(在您的例子中是while循环)都会阻止程序继续到下一个,因此永远不会到达mainloop()

至于您不知道何时何地创建按钮的问题,您应该看看这个示例代码,作为如何设置tkinter GUI的框架

from tkinter import Tk, Label, Button

class MyFirstGUI:
    def __init__(self, master):
        self.master = master
        master.title("A simple GUI")

        self.label = Label(master, text="This is our first GUI!")
        self.label.pack()

        self.greet_button = Button(master, text="Greet", command=self.greet)
        self.greet_button.pack()

        self.close_button = Button(master, text="Close", command=master.quit)
        self.close_button.pack()

    def greet(self):
        print("Greetings!")

root = Tk()
my_gui = MyFirstGUI(root)
root.mainloop()

如您所见,它在类中构建GUI。其中一个非常有用的方面是创建GUI窗口时调用的\uuu init\uu()函数。在本例中,在启动功能中创建了一个按钮。然后,按钮触发的功能定义如下

这里有一个指向教程的链接,上面的示例代码来自:https://python-textbok.readthedocs.io/en/1.0/Introduction_to_GUI_Programming.html 祝你好运

相关问题 更多 >