我并不完全确定如何表达这一点,但我正在创建一个包含一些ASCII艺术的Tkinter应用程序。部分是艺术,但部分是用户想要阅读的文本。原始文本艺术看起来像这样:
_______________________________________
| . |
| +===================================+ |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| +===================================+ |
|_______________________________________|
\ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ \
|\ \__\__\__\__\__\__\__\__\__\__\_____ \
\ \ \___\__\__\__\__\__\__\__\__\__\____ \
\ \ \____\__\__\__\__\__\__\__\__\______ \
\ \ \______\__\__\__\__\__\__\__\_______ \
\ \ \__\__\__\_________________\__\_____ \
\ \ \
\ \ \
\ \ \
\ \________________________________________\
\|________________________________________|
然而,除了屏幕上的35个空格外,我每行有9 %s
个,除了第一个和最后一个,两边各有两个空格,每个都有31个字符。 (看起来这是一个变量):
comp = r"""
_______________________________________
| . |
| +===================================+ |
| | | |
| | %s | |
| | %s | |
| | %s | |
| | %s | |
| | %s | |
| | %s | |
| | %s | |
| | %s | |
| | %s | |
| | | |
| +===================================+ |
|_______________________________________|
\ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ \
|\ \__\__\__\__\__\__\__\__\__\__\_____ \
\ \ \___\__\__\__\__\__\__\__\__\__\____ \
\ \ \____\__\__\__\__\__\__\__\__\______ \
\ \ \______\__\__\__\__\__\__\__\_______ \
\ \ \__\__\__\_________________\__\_____ \
\ \ \
\ \ \
\ \ \
\ \________________________________________\
\|________________________________________|
"""
我还有一系列"屏幕"对于计算机,这些列表包含9个元素,每个元素正好有31个字符。下面是我在屏幕上显示内容的示例,假设ASCII计算机已经被定义为原始文本多行字符串,如上所述:
def change_screen():
comp_art.set(comp % tuple(screen1))
blank = [" "*31, " "*31, " "*31, " "*31, " "*31, " "*31, " "*31, " "*31, " "*31]
screen1 = ["31 characters of text", "31 char..."] #List with 9 elements
from tkinter import *
root = Tk()
root.option_add("*Label.Font", "courier")
comp_art = StringVar()
comp_art.set(comp % tuple(blank))
comp_label = Label(root, textvariable=comp_art, justify=LEFT)
change_button = Button(root, text="TEST", command=change_screen)
comp_label.pack()
change_button.pack()
root.mainloop()
运行时,此代码会生成一个带有空白计算机艺术和其下方按钮的窗口。按下按钮后,列表screen1
中的文本将显示在计算机的屏幕上。这很好,但因为这是一个游戏,我想一次显示这样的消息。我尝试过定义第三个开始完全空白的列表,并在for
循环中将列表中的每个元素从空白更改为文本,一次一个。它看起来像这样:
import time
def display(x):
# x is a list, like screen1 above, that I want to display one line at a time
show_list = [x[0]]
for _ in range(8):
show_list.append(" "*31)
# Makes the list 9 elements long, and all spaces except for the first
# one, which is the first element of x, the one I want to display
for n in range(x):
comp_art.set(comp % tuple(show_list)
time.sleep(0.5)
show_list[n] = x[n]
该函数的后半部分,即第二个for
循环,更改了我StringVar()
comp_art
,我之前分配给了一个Label。它始终使屏幕显示show_list的内容,但每次我更改show_list时,我也comp_art.set()
,这反过来应该改变计算机的外观,因为它是与StringVar()
关联的comp_label
。但是,当我运行该代码时,它不起作用。它改变了计算机的显示,但不是一次只做一行,而是等待4.5秒(因为time.sleep(0.5)
),而屏幕保持空白然后显示我的内容想要它。有谁知道为什么,或者我能做些什么不同的事情?尽管我付出了最大的努力,但我还是没有想到比这更有效的东西,因为如果我使用多个标签,那么它们之间就会存在差距,并且ASCII艺术已全部关闭。
我也想知道是否有办法解决问题?#34;筑巢" StringVar()
秒。例如,当您在tkinter中定义标签并将其作为StringVar赋予textvariable
时,标签将在变量更改时自动更新。有没有办法在StringVar()
中添加StringVar()
,这样当您更新一个StringVar()
时,较大的一个会更新,如果是分配给标签,该标签将更新。有没有办法做到这一点? tkinter中的trace()
函数会帮助我做到这一点,如果是的话,我会做什么?
对于这个问题的淫秽篇幅感到抱歉...感谢您花时间阅读它,并感谢您提供任何和所有答案。
编辑:我还做了几件事,包括编写四个独立的函数来编辑计算机的前四行,每个函数调用time.sleep(0.5)
定义和打包后标签,但在root.mainloop()
之前,我一次调用这些函数。然而,这样做会创建一个窗口,就像我想要的那样,但窗口保持完全黑色,直到四个功能成功运行,此时标签进入屏幕,所有四个更改的行。我想要的动画片段仍然无法正常工作。现在,我有一个名为comp_screen
的第三个列表,它目前等于blank
,但我可以更改。我还有一个函数update_screen(),它可以更新计算机StringVar()
。我做错了什么?
comp_screen = blank
def update_screen():
computer.set(art.comp % tuple(comp_screen))
def intro_f1():
wait(0.5)
comp_screen[0] = intro[0]
update_comp()
def intro_f2():
wait(0.5)
comp_screen[1] = intro[1]
update_comp()
def intro_f3():
wait(0.5)
comp_screen[2] = intro[2]
update_comp()
def intro_f4():
wait(0.5)
comp_screen[3] = intro[3]
update_comp()
# The Tk() code that makes the window and label (see above - no use typing
# it out again). I have not yet called mainloop().
intro_f1()
intro_f2()
intro_f3()
intro_f4()
root.mainloop()
答案 0 :(得分:1)
你所拥有的display
函数并不能满足你的需要,因为它在tkinter
事件循环之外运行,它处理重绘屏幕之类的内容。当您的循环正在运行时,窗口的其余部分将停止,无法更新并显示您已设置的新文本。
因此,不是用一个等待这样的循环编写一个函数,而是需要编写一些可以重复调用的东西(可能来自一个计时器),并且每次都更新一行。
同样的一般想法也可能是您应该如何处理“嵌套StringVar
”问题。不要试图让一个人直接包含另一个,而是编写一个从“内部”文本中提取文本的函数,并将其放在“外部”StringVar
中的正确位置。然后在正确的时间调用该函数。