Обновление окна tkinter в фоновом режиме - PullRequest
0 голосов
/ 21 января 2020

Я пытаюсь сделать игру python, и в идеале мне нужно создать простой tkinter GUI, состоящий из пары кнопок и ввода текста.

Формат игра в настоящее время состоит из нескольких функций, которые по большей части начинаются с print(something), затем идут input(bunch of stuff\nbunch of stuff\n) и, наконец, последовательность тестов «если / еще», чтобы получить ввод пользователя и выполнить другое действие. (обычно вызывает другую функцию)

Вот как это выглядит в настоящее время:

        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

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Вот небольшой демонстрационный код в качестве примера структуры вашей игры. В этом примере экран очищается от всех кнопок, надписей и записей, затем вам нужно создать новые в следующей сцене. Это поддерживает сцены, которые имеют разные макеты. Если вы хотите, чтобы в каждой сцене были только кнопка, метка и запись, вы можете изменить эту структуру, чтобы сэкономить ваши усилия по созданию виджетов. Попробуйте запустить этот код, чтобы увидеть, что он делает, затем посмотрите на код и комментарии, чтобы узнать, как он работает.

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()
0 голосов
/ 22 января 2020

Полный проект был слишком сложным, чтобы тщательно его просмотреть, но я вижу несколько вещей, которые не укладываются.

Печать не go для этикеток tkinter, она просто идет на консоль. Вы можете обновить метку tkinter новым текстом, связав StringVar с аргументом textvariable метки. Значение StringVar можно изменить с помощью метода set ().

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

У вас есть while True l oop с update () в конце, а также mainl oop (). Вы должны выбрать одно или другое, потому что эти sh почти одинаковые. Кроме того, независимо от того, что из этих программ встречается первым (в то время как l oop, в вашем случае), не позволяет программе переходить к следующему, поэтому mainl oop () никогда не достигается.

Что касается вашей проблемы не зная, когда и где создавать кнопки, вы должны взглянуть на этот пример кода в качестве скелета для настройки 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 в классе. Одним из очень полезных аспектов этого является функция __ init __ (), которая вызывается при создании окна GUI. В этом примере в функции инициирования создается кнопка. Затем функция, вызываемая кнопкой, определяется ниже.

Вот ссылка на учебник, из которого приведен пример кода выше: https://python-textbok.readthedocs.io/en/1.0/Introduction_to_GUI_Programming.html Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...