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控制一下的話會好一些,不知道這里有沒有更好的處理辦法