1. 程式人生 > >python——Tkinter圖形化介面及threading多執行緒

python——Tkinter圖形化介面及threading多執行緒

Tkinter模組("Tk 介面")是Python的標準Tk GUI工具包的介面.Tk和Tkinter可以在大多數的Unix平臺下使用,同樣可以應用在Windows和Macintosh系統裡.Tk8.0的後續版本可以實現本地視窗風格,並良好地執行在絕大多數平臺中

Tkinter包含了若干模組. Tk介面被封裝在一個名為 _tkinter 二進位制模組裡( tkinter 的早期版本). 這個模組包含了Tk的低階介面,因而它不會被程式設計師直接應用.它通常表現為一個共享庫(或DLL檔案),但在一些版本中它與Python直譯器結合在一起

在Tk介面的附加模組中,Tkinter包含了一些Python模組,儲存在標準庫的一個子目錄裡,稱為 tkinter。 其中有兩個重要的模組,一個是Tkinter自己,另一個叫做Tkconstants:前者自動匯入後者,所以你如果使用Tkinter,僅僅匯入一個模組就可以
import Tkinter
或者更常用的:
from Tkinter import *

簡單列出一些常見的控制元件


下面具體舉例說明一下,樣例如下圖:


首先我們指定一個Tkinter物件

root=Tk()

設定標題

root.title('九日王朝')

圖片的呈現方式有很多種,這裡採用的是先設定一個label控制元件,使其圖片在label中呈現

image2 =Image.open(r'ParticleSmoke.png')
background_image = ImageTk.PhotoImage(image2)
textlabel=Label(root,image=background_image)
textlabel.grid()

這裡注意,grid是佈局方法,也就是說我們每次設定一個控制元件都需要將其grid,否則將不顯示

滾動文字框ScrolledText,其可以設定字型,顏色等引數

text=ScrolledText(root,font=('微軟雅黑',10),fg='blue')

text.grid()

按鈕

button=Button(root,text='屠龍寶刀 點選就送',font=('微軟雅黑',10),command=fun)
button.grid()

以及可變的文字,文字我們採取的也是放在label裡的方式

var=StringVar()#設定變數
label=Label(root,font=('微軟雅黑',10),fg='red',textvariable=var)
label.grid()
var.set('我不斷的洗澡,油膩的師姐在哪裡')

如果在程式執行中,需要對文字進行更改時,可以再次使用var.set

最後,我們通過mainloop()進入到事件(訊息)迴圈,也就是維護我們的視窗介面

下面介紹一下threading多執行緒模組

threading.Thread(target=函式名args=(呼叫引數,注意最後要有一個‘,’))可以例項化一個多執行緒物件

通過start就可以開啟

這裡要說一下th.setDaemon(True)守護執行緒

python中得thread的一些機制和C/C++不同:在C/C++中,主執行緒結束後,其子執行緒會預設被主執行緒kill掉。而在python中,主執行緒結束後,會預設等待子執行緒結束後,主執行緒才退出。

那麼尷尬的問題就出現了,有一種情況,比如說在linux系統中存在脫離於終端的執行緒,即父程序在建立子程序之後先於子程序退出,會造成這個子程序變為“孤兒程序”

如果你忘記殺死子執行緒,那麼好了,你殺主執行緒的時候其就會掛起等待直至子執行緒結束,所以為了避免這樣的情況,python有兩個函式管理執行緒:join和setDaemon

join:如在一個執行緒B中呼叫threada.join(),則threada結束後,執行緒B才會接著threada.join()往後執行。
setDaemon:主執行緒A啟動了子執行緒B,呼叫b.setDaemaon(True),則主執行緒結束時,會把子執行緒B也殺死,與C/C++中得預設效果是一樣的。

說了這麼多就是大家最好養成習慣,一般情況下,在start前面加一下setDaemon(True)

下面放出完整程式碼,以多執行緒計數為例:

#coding:utf-8
from Tkinter import *
from ScrolledText import ScrolledText #文字滾動條
import threading
import time
from PIL import ImageTk,Image



def count(i):
     for k in range(1, 100+1):
        text.insert(END,'第'+str(i)+'執行緒count:  '+str(k)+'\n')
        time.sleep(0.001)
          

def fun():
    for i in range(1, 5+1):
        th=threading.Thread(target=count,args=(i,))
        th.setDaemon(True)#守護執行緒
        th.start()
    var.set('MDZZ')



root=Tk()
root.title('九日王朝')  #視窗標題
root.geometry('+600+100')#視窗呈現位置
image2 =Image.open(r'ParticleSmoke.png')
background_image = ImageTk.PhotoImage(image2)
textlabel=Label(root,image=background_image)
textlabel.grid()
text=ScrolledText(root,font=('微軟雅黑',10),fg='blue')
text.grid()
button=Button(root,text='屠龍寶刀 點選就送',font=('微軟雅黑',10),command=fun)
button.grid()
var=StringVar()#設定變數
label=Label(root,font=('微軟雅黑',10),fg='red',textvariable=var)
label.grid()
var.set('我不斷的洗澡,油膩的師姐在哪裡')
root.mainloop()



最後說一下,多執行緒無限呼叫ScrolledText.insert()插入文字時,可能會造成程式卡頓甚至奔潰

如果用sleep控制一下的話會好一些,不知道這裡有沒有更好的處理辦法