2016-01-23 82 views
2

我不完全確定如何對此進行描述,但是我創建了一個包含一些ASCII藝術的Tkinter應用程序。部分是藝術,但部分是用戶打算閱讀的文本。原始文本的藝術是這樣的:我怎麼會把StringVar()放在StringVar()中?

_______________________________________ 
|     .     | 
| +===================================+ | 
| |         | | 
| |         | | 
| |         | | 
| |         | | 
| |         | | 
| |         | | 
| |         | | 
| |         | | 
| |         | | 
| |         | | 
| |         | | 
| +===================================+ | 
|_______________________________________| 
\ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ \ 
|\ \__\__\__\__\__\__\__\__\__\__\_____ \ 
\ \ \___\__\__\__\__\__\__\__\__\__\____ \ 
\ \ \____\__\__\__\__\__\__\__\__\______ \ 
    \ \ \______\__\__\__\__\__\__\__\_______ \ 
    \ \ \__\__\__\_________________\__\_____ \ 
    \ \          \ 
    \ \          \ 
     \ \          \ 
     \ \________________________________________\ 
     \|________________________________________| 

而是在屏幕上的35位,但是,我有9 %s的每一行中,除第一個和最後一個,有兩個空格兩側,使得每個長31個字符。 (它看起來像這樣作爲一個變量):

comp = r""" 
_______________________________________ 
|     .     | 
| +===================================+ | 
| |         | | 
| | %s | | 
| | %s | | 
| | %s | | 
| | %s | | 
| | %s | | 
| | %s | | 
| | %s | | 
| | %s | | 
| | %s | | 
| |         | | 
| +===================================+ | 
|_______________________________________| 
\ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ \ 
|\ \__\__\__\__\__\__\__\__\__\__\_____ \ 
\ \ \___\__\__\__\__\__\__\__\__\__\____ \ 
\ \ \____\__\__\__\__\__\__\__\__\______ \ 
    \ \ \______\__\__\__\__\__\__\__\_______ \ 
    \ \ \__\__\__\_________________\__\_____ \ 
    \ \          \ 
    \ \          \ 
     \ \          \ 
     \ \________________________________________\ 
     \|________________________________________| 
""" 

我也有一系列的「屏幕」爲計算機,其是與每個恰好31個字符恰好9個元素列表。下面是我可以做什麼來顯示屏幕上的內容,假設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,這是我之前分配到一個標籤。它總是讓屏幕顯示show_list的內容,但每次我更改show_list時,我也是comp_art.set(),這反過來應該改變計算機的外觀,因爲那是與comp_label關聯的StringVar()。但是,當我運行該代碼時,它不起作用。它改變了計算機的顯示器,但並不是一次只顯示一行,而是等待4.5秒(因爲time.sleep(0.5)),而屏幕保持空白,然後顯示我想要的內容。有誰知道爲什麼,或者我可以做什麼不同?儘管我盡了最大的努力,但我一直沒有想到任何比這更有效率的東西,因爲如果我使用多個標籤,它們之間就會存在差距,而ASCII藝術也是如此。

我也想知道是否有一種方法來排序「巢」StringVar() s。例如,當你在tkinter中定義一個標籤並將它作爲一個StringVar對象時,該標籤將隨着該變量的變化而自動更新。有沒有一種方法可以在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() 

回答

1

display功能,您有沒有做你想做的,因爲它的運行tkinter事件循環處理的東西一樣重繪屏幕之外。在循環運行時,窗口的其餘部分會停滯,無法更新並顯示您設置的新文本。因此,不必編寫一個帶有等待的循環的函數,而是需要編寫一些可以重複調用(可能來自定時器)的內容並每次更新一個新行。

相同的一般想法可能也是你應該如何處理你的「嵌套StringVar」問題。而不是試圖讓一個直接包含另一個,編寫一個函數,從「內部」的文本中提取文本,並將其放在「外部」StringVar的正確位置。然後讓這個功能在正確的時間被調用。

+0

我沒有意識到窗口在函數運行時停頓 - 謝謝。在發生了一些奇怪的事情之後,我習慣於在'mainloop()'之外編寫函數,但也許我會編寫一個更新單行的函數,然後在窗口代碼中多次調用該函數。謝謝! –

相關問題