為什麼很多Python開發者寫GUI不用Tkinter,而要選擇PyQt和wxPython或其他?

剛接觸 Python 一個月。最近在寫一個桌面應用,GUI 用的 Tkinter。

寫的過程中有幾個地方不是很明白,請教一位 Python 比較牛逼的朋友。

他看到後就說,你怎麼用 Tkinder 啊?!Tkinter 坑多的數不清,為什麼不用 PyQt 或者 wxPython?然後建議我換,之後巴拉巴拉說了一堆 Tkinter 的缺陷。我很不解就百度了一下,發現網上真的很多人說 Tkinter 不好。

我認為 Tkinter 作為 Python 的標準 GUI 庫,應該支持是最好的啊?為什麼那麼多人吐槽,是真的不好嗎?


真心不好用啊哭……我是wx黨,不過看起來qt也不錯。都是比較完整的。

TK庫對於python來說就是:哦哦哦有個現成的我們把它放進去吧。

特別丑特別簡陋……

wx那麼樸素的東西還有圖元啊圖表啊甚至OpenGL啦這些東西,TK可是……(陷入了長久的思考


Tkinter也有漂亮的皮膚,最大的問題是tkinter的文檔太爛,你查API都不知道在哪裡查,書也稀少,好像就一本,而且很爛。

wxpython雖然文檔也超爛,但還是有個完整的API文檔,並且有兩本書(雖然兩本書都超爛無比),以及相當驚艷的demo,對著demo,你就能寫很漂亮的GUI


因為Tk戰鬥力只有5。

「標準」的GUI庫基本都是只能湊合用的玩意。


先說下我個人的情況,使用Matlab已3年有餘,期間編寫過幾個專業方面的計算程序以及做過數個地鐵振動信號處理分析方面的項目,有一定的編程基礎。大概4個月前正式學習Python,用了2個月時間過了一遍Python的基本知識及語法,然後用了2~3天(課餘時間)的時間仿照扇貝網背誦英語單詞的模式,寫了一個背誦日語單詞的軟體Anki的底層代碼(200餘句),輸入輸出都在shell里,用起來很不方便。然後開始嘗試GUI,首先選擇的就是Python自帶的Tkinter,然後在網上找了Tkinter的相關文檔:第一份是Tkinter簡明教程,不知所云,幾乎沒什麼幫助;第二份是2014年度辛星Tkinter教程第二版,內容淺顯易懂;第三份是Python GUI Programming Cookbook,內容詳細,幫助很大。大概用了5-6天的時間,邊看文檔寫出了帶有簡單GUI界面的Anki2.0。又經過之後的組件升級,增加了許多功能,更新到了Anki3.2。先上圖:

先上結論:Tkinter真的不像大家說的那麼差,基本的功能都能實現,而且簡單易學容易上手。對於界面顏值沒有太高要求的,用Tkinter寫GUI是不錯的選擇。

1、組件

本軟體中用到了大概5個組件:

1.1、Button按鈕

語法如下:創建了名為Play播放的按鈕,綁定了命令sound_play。

b1 = ttk.Button(xin, text = "Play
播放", width = 10, command = sound_play)
b1.grid(row=3,column=4, padx=10, pady=10)

1.2、Label標籤

語法如下:創建了名為Model的標籤。

mm1 = ttk.Label(xin, text = "Model")
mm1.grid(row=0,column=1)

1.3、Combobox下拉列表

number = tk.StringVar()
LessonChosen = ttk.Combobox(xin, width=12, textvariable=number, state="readonly")
LessonChosen["values"] = lesson_name # 設置下拉列表的值
LessonChosen.grid(column=2, row=1) # 設置其在界面中出現的位置 column代表列 row 代表行
LessonChosen.current(lesson_name.index(str(WW[0]))) # 設置下拉列表默認顯示的值,0為 LessonChosen["values"] 的下標值

1.4、LabelFrame

labelframe1 = ttk.LabelFrame(xin, text="単語 (第 課,第 個單詞)", height = 80, width=300) # 信息區
labelframe1.grid(row=3,column=1, columnspan = 3 , padx=10, pady=10)
labelframe1.propagate(0) # 使組件大小不變,此時width才起作用
ttk.Label(labelframe1, text = " ",font = ("Mincho, 20")).pack(fill="both", expand="yes")

1.5、Radiobutton單選按鈕

#單選按鈕radiobutton
v=tk.IntVar()
v.set(1)
#f1.bind("&",word_know)
f1 = tk.Radiobutton(xin,text = "Know", font =24, variable=v,value=1, command = word_know)
f1.grid(row=6,column=2)
f1.configure(state="disabled")
#f2.bind("&",word_unknow)
f2 = tk.Radiobutton(xin,text = "Unknow",font =24,variable=v,value=2, command = word_unknow)
f2.grid(row=6,column=3)
f2.configure(state="disabled")

下面貼一段與『Play播放』按鈕綁定的sound_play函數的命令:

#Play按鈕
def sound_play():
import winsound
import time
import os
global xin
global word_list
if back_canshu == 0:
if len(word_list_now)==0:
showinfo(title = "Message", message = "恭喜,本次單詞已經背完!")
if BSM == 0:
word_list1 = [R[1:3]]
for i in range(len(word_list)):
if len(word_list[i])&>=6:
if word_list[i][5]!="":
word_list1.append(word_list[i])
del word_list
word_list =word_list1
#保存file.txt
import os
os.remove(r".file.txt")
#寫出單詞表信息
write_file_word(word_list,r".file.txt")
else:
if len(word_list_now)&>=1:
lesson = int(word_list_now[0][0])
mn = int(word_list_now[0][1])
if os.path.exists(r".audioL"+str(lesson)+"L"+str(lesson)+"_"+str(mn)+".wav")==False:
winsound.PlaySound(r".audioWindows_Background.wav", winsound.SND_FILENAME|winsound.SND_ASYNC)
#第三行:labelframe單詞
labelframe1 = ttk.LabelFrame(xin, text="単語 (第 "+str(lesson)+" 課,第 "+str(mn)+" 個單詞)", height = 80, width=300) # 信息區
labelframe1.grid(row=3,column=1, columnspan = 3 , padx=10, pady=10)
labelframe1.propagate(0) # 使組件大小不變,此時width才起作用
ttk.Label(labelframe1, text = word_list_now[0][2], font = ("Mincho, 20")).pack(fill="both", expand="yes")
else:
winsound.PlaySound(r".audioL"+str(lesson)+"L"+str(lesson)+"_"+str(mn)+".wav", winsound.SND_FILENAME|winsound.SND_ASYNC)
else:
lesson = int(word_back[-back_canshu][0])
mn = int(word_back[-back_canshu][1])
if os.path.exists(r".audioL"+str(lesson)+"L"+str(lesson)+"_"+str(mn)+".wav")==False:
winsound.PlaySound(r".audioWindows_Background.wav", winsound.SND_FILENAME|winsound.SND_ASYNC)
else:
winsound.PlaySound(r".audioL"+str(lesson)+"L"+str(lesson)+"_"+str(mn)+".wav", winsound.SND_FILENAME|winsound.SND_ASYNC)

2、軟體封裝打包

Python Tkinter打包封裝的方法有:PyInstaller, py2exe, wxPython等方法。答主只是用了PyInstaller來打包,感覺特別好用,對其它方法不做評論。

網上有很多打包方法:Python | 用Pyinstaller打包發布exe應用,請自行參考!

要說的是,打包過程中可以添加如下指令,自行嘗試打包後的差異:

-w指令,在指令內加入-w命令可以屏蔽發布的exe應用帶命令行調試窗口;

-F指令,使用-F指令可以把應用打包成一個獨立的exe文件,否則是一個帶各種dll和依賴文件的文件夾;

-i指令,可以自定義圖標。

簡單寫一下用pyinstaller打包軟體的過程:

①準備好打包文件:

aiueo.py為代碼,audio文件夾、tango文件夾和file.txt為程序關聯調用的文件,a.ico為軟體圖標。

②在安裝的Python文件夾下的Scripts目錄下(包含pyinstaller.exe),shift+右鍵&>&>在此處打開命令窗口:

③輸入:pyinstaller.exe -i C:UsersNaplesaiueoa.ico -w C:UsersNaplesaiueoaiueo.py 回車。

-i C:UsersNaplesaiueoa.ico 為圖標所在的目錄;

-w C:UsersNaplesaiueoaiueo.py 為程序所在目錄。

④在C:Python34Scripts目錄下就會出現這三個文件:

可以將第一、三個文件刪除,只留下dist文件夾。將和程序關聯的audio文件夾、tango文件夾和file.txt三個文件夾拷貝到dist/aiueo/目錄下。雙擊aiueo.exe,程序就可以使用了。

可以發送桌面快捷方式,也可以將軟體打包拷貝到相同平台下的電腦上使用。

軟體是根據2017年度赴日留學博士班基礎日語教程《実力日本語》編寫,包含了基礎日語L1~L60課的單詞和錄音,感興趣的可以嘗試下載,鏈接:http://pan.baidu.com/s/1i4O3gRN 密碼:a8kq

Python教程:

Tkinter簡明教程:http://pan.baidu.com/s/1o8v3baq

2014年度辛星Tkinter教程第二版:http://pan.baidu.com/s/1hr6ortE

Python GUI Programming Cookbook:http://pan.baidu.com/s/1eSimgQA

以上。


問題在於,想要做出同樣好看的 GUI,用 Tkinter 所要花的時間要多得多。。


雖然不知道TKinter少了哪些,但我們既然是小馬過河,大牛們都說有坑。我們就隨大流吧。

簡單UI推薦Enthought的Traits/TraitsUI。簡單粗暴有效。

如果需要構建大型應用,推薦使用Enthought Tool Suite裡面其他的東西,可以構建插件來擴展自己的應用框架。所以從簡單到複雜,全程覆蓋。不僅限於UI框架。而是桌面應用框架。

提一句,Enthought貢獻了Scipy等著名的Python package。


最近剛用Tkinter寫完一個GUI程序,代碼估計有一千行吧,這也是我第一次使用Tkinter,使用下來的感受是——累!主要體現在如下幾點:

1.Tkinter包含常見GUI模塊(或者類,或者框架啥的,比如Java裡面的Swing)的主要功能,但是相當一部分是沒有的。這樣帶來的好處是Tkinter給人一種非常簡單的感覺,但是也弱化了其功能。舉個栗子:Tkinter中輸入框較Entry,本想實現輸入框中內容被改變時,該內容文字顏色變為紅色的功能,但是找了半天,沒有,或者是藏得很深,讓人誤以為沒有 。

(╯‵□′)╯︵┻━┻

這樣的情況還有很多,而且其API寫的真的簡單,想要找到想要的屬性、方法確實得費點勁。

2.Tkinter的布局是通過代碼完成的,要是你的界面上有個幾十個控制項,寫起來也是很酸爽。並且布局的參數,例如padx=3,這個3在Windows和Linux平台上是不一樣的,換言之你在Windows上寫好的GUI放在Linux上可能就會亂成一鍋粥。

3.也算不上缺點也不算是優點。Tkinter模塊本身是沒有下拉列表這個東西的,但是Tkinter包含了ttk,tik之類的主體,這個裡面有一個ttk.Combobox。但是這樣真的好呢?找個控制項要翻遍整個API,就不能集中一下?就不能再Tkinter模塊本身中包含一下?

5.既然說到了ttk,那就講講這貨。Tkinter模塊,及Tkinter.ttk模塊中,相同名字的控制項使用方法,屬性列表,控制項方法,事件是不一樣的,有相同,但大多是不同的。

6.多人都說Tkinter有主題,也可以編寫漂亮的界面,我就想知道用Tkinter的人有多少還會專門寫編寫主題代碼。反正我用Tkinter就是圖個方便,Python自帶的優點還是有的。

7.Tkinter確實簡單易用,但是效率很低。雖說寫個帶有兩Label,兩Entry,還有兩button的登錄界面確實用Tkinter幾行代碼就解決了,這一波算你Tkinter贏。但是你確定你只是要寫這樣GUI?最初我的也是這樣想的,但是程序越寫越複雜,功能越寫越完善,這時候就該懷疑人生了。從文檔中找控制項、方法、事件、屬性的時候就知道這個過程有多效率低下。

總結一番,Tkinter想說愛你不容易(這話出自哪裡來著?),想要長期在Python上做GUI開發的話,還是換方案吧,裡面那麼多坑,總有一款適合你。(&>^ω^&<)喵


軟體開發中,用不用某個庫,更多的不是看所謂個人喜歡,而是效率和需求!

舉個簡單例子,給測試部門做一個帶界面的自動化測試工具,完全沒有必要去用pyqt,當然是怎麼省時省力怎麼來,誰管你界面美不美?對不對,就是這個道理,不同的場合,不同的需求,這個時候用tkinter就很簡單方便

如果是說要針對用戶的場合,對美觀有要求,tkinter確實弱了一點,這個時候可以選用更好的比如pyqt

但是並不是說tkinter一錢不值,它也有自己的優勢,對於某些人,請不要因為自己不會就說它怎麼怎麼爛,說有坑的,坑你在哪裡了,說出來看看,是自己水平不行還是真的坑,所以不要人云亦云

另外,tkinter資料並不少,而且tkinter是有拖拽控制項的開發工具的,說資料少,只能說明你自己連個資料都不會找,tkinter只是中文的資料少而已

資料:

tkinter關於ttk應用的詳細教程-CSDN下載

python-tkinter官方高清文檔-CSDN下載

tkinter高清文檔-CSDN下載

Python GUI之tkinter概述

至於有人提到的拖拽控制項工具,tkinter是有的,只是不太好用,我這裡還是補充一下吧

A Python GUI Generator


昨天也在做同樣的選擇。發現Tk最後一次更新於2009年,wx最後一次更新於2016年~


體驗過,簡單說下:PyQt畫GUI的時候超級爽;Tk只是手寫過界面,用著不是很爽。


其實你要知道,GUI最後的生成是靠OS來做的,所以不論是TK,wx,qt,最終調用OS的功能(模塊)來完成GUI的。這樣的話,雖然TK是Python的標準庫,但其實有沒有很好的和OS合作才是好的GUI庫的標準之一。

但是,TK真的很簡單。裝了python的電腦都能運行。如果你只是想寫個小工具,而且有時想在別的電腦上展示(炫)一下。用TK吧。


tkinter文檔真的差,因為寫這文檔的人本身都會用tk,動不動就說去看tk的文檔 然而點過去時候發現看不懂。


首先並不是不好.

不清楚你朋友說的坑是指哪方面?Tk相對兩外兩個來說功能是要少很多,但也有大牛豐富了一下,

比如:

https://docs.python.org/2/library/ttk.html

Python megawidgets download

Tkinter Table download

UI要求不高的拿Tk寫,要比另兩個方便.


查閱下python gui wiki

GuiProgramming - Python Wiki

基本上樓上列出來的都在這份wiki表中。

很贊同 @俠之大者鍵盤俠 的回答,選開發工具本來就是在權衡利弊,沒有十全十美的東西,所以要看自己的需求。

我本身用python腳本跑機器學習的多,gui用的不多,最近在數據整理部分有個小需求,我想做成一個工具來使用。查閱上述列表,由於我最看重的是更新日期,儘管表中的順序是按字母順序排序的,但排第一位的appJar恰巧是更新最新的庫,我就試用了一下。這個庫是基於tk的,但用起來確實超級簡單,對我們追求效率的人來說學習成本真是超級小,所以如果有同樣需求的童鞋可以考慮這個庫。


有了MFC基礎的我暑假剛自學完python基本語法學到GUI Tkinter翻了幾頁書做了幾個簡單的窗口控制項書上關於GUI就沒別的內容了??...他們都說MFC辣雞然並卵啊點點圖形隨便在類里碼幾個代碼就行了而且功能廣什麼都能做...你Tkinter雖然簡單但是代碼從頭到尾自己碼而且能實現的東西太有限了...學習資料也不多...棄坑


本來是決定用tkinter的,基本上什麼都有,畫圖還可以用matplotlib。但是開工之前突然發現linux 下tkinter不是標準模塊。雖然我不用跨平台,但是對tkinter的地位開始懷疑。

隨後改用pyqt了


看需求,小程序用TKinter寫也無妨,否則就要換個圖形庫了。

以自身為例,前陣子要為實驗室寫個小型的記錄管理器,把錄入的標註信息存放在對應XML文件里。這裡主要是需要使用一個網格控制項,方便用戶直接在上面編輯。TKinter里只有一個treeView倒是可以用來列印表格,這就已經很勉強了,更別說更訂製話的需求了。

wxpython剛好有一個(特別製作的)網格(grid)控制項,所以就用它了。wxpython的文檔詳實,可以邊看文檔邊做,完全不需要額外的教程。實際上,做圖形界面相對都比較簡單,重要的是在功能、界面以及軟體結構上的設計。這也是為什麼wxpython相關教程很少的原因。

最後實現效果圖,與原始設計比有點簡化和改動。夠用就行了。

設計圖


我發現Tkinter不能像Winform、wpf、Qt那樣拖控制項寫GUI,實時的所見即所得無從談起,這能忍?


Tk仔細學習還有可以做很多事情的,這是我網上找的代碼。配配色也是可以滿足個人需求的


明天聽一天tkinter的課,然後回家摸索一下。。。


推薦閱讀:

GUI 設計師張曉翔是個什麼樣的人?
2017年用C++開發GUI應用的最佳選擇是什麼?
visual basic 如何禁用dpi縮放?

TAG:Python庫 | PyQt | GUI設計 | wxPython | tkinter |