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)

 

下面放出完整代碼,以多線程計數為例:

 

 

[python]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. #coding:utf-8  
  2. from Tkinter import *  
  3. from ScrolledText import ScrolledText #文本滾動條  
  4. import threading  
  5. import time  
  6. from PIL import ImageTk,Image  
  7.   
  8.   
  9.   
  10. def count(i):  
  11.      for k in range(1, 100+1):  
  12.         text.insert(END,'第'+str(i)+'線程count:  '+str(k)+'\n')  
  13.         time.sleep(0.001)  
  14.             
  15.   
  16. def fun():  
  17.     for i in range(1, 5+1):  
  18.         th=threading.Thread(target=count,args=(i,))  
  19.         th.setDaemon(True)#守護線程  
  20.         th.start()  
  21.     var.set('MDZZ')  
  22.   
  23.   
  24.   
  25. root=Tk()  
  26. root.title('九日王朝')  #窗口標題  
  27. root.geometry('+600+100')#窗口呈現位置  
  28. image2 =Image.open(r'ParticleSmoke.png')  
  29. background_image = ImageTk.PhotoImage(image2)  
  30. textlabel=Label(root,image=background_image)  
  31. textlabel.grid()  
  32. text=ScrolledText(root,font=('微軟雅黑',10),fg='blue')  
  33. text.grid()  
  34. button=Button(root,text='屠龍寶刀 點擊就送',font=('微軟雅黑',10),command=fun)  
  35. button.grid()  
  36. var=StringVar()#設置變量  
  37. label=Label(root,font=('微軟雅黑',10),fg='red',textvariable=var)  
  38. label.grid()  
  39. var.set('我不斷的洗澡,油膩的師姐在哪里')  
  40. root.mainloop()  



 

 

 

 

最后說一下,多線程無限調用ScrolledText.insert()插入文本時,可能會造成程序卡頓甚至奔潰

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM