這一節記錄的是我在使用python tkinter時的一些筆記。
背景:現在需要建構一個簡易的聊天工具,說簡易是因為确實隻需要很簡單的幾個界面,包括一個登陸界面、一個好友清單和單擊好友時彈出好友對話框可以交談,我們這裡隻需要建立簡單的界面(不包括業務),是以選擇用tkinter這個子產品來實作。
要點一、神馬是tkinter?
Tkinter子產品("Tk 接口")是Python的标準Tk GUI工具包的接口.Tk和Tkinter可以在大多數的Unix平台下使用,同樣可以應用在Windows和Macintosh系統裡.,Tk8.0的後續版本可以實作本地視窗風格,并良好地運作在絕大多數平台中.(摘自百度百科)想要檢視你的Tkinter版本,隻需要在python指令行模式下輸入print Tkinter.TkVersion即可,筆者的版本是8.5。
要點二、安裝
一般情況下,安裝python時,自帶安裝了Tkinter,并且與python的版本相對應,例如python2.7.3對應的應該是8.5版本,其餘的我倒不是很熟悉。但有些預安裝的python可能沒有帶上tkinter,例如我在虛拟機Fedora17上的python并沒有自帶tkinter,這時候解決辦法是使用yum install tkinter指令即可。
要點三、登陸框
View Code
1 # -*- coding: utf-8 -*-
2 import Tkinter
3 from Tkinter import *
4 from multiprocessing import Process,Pipe
5 class Login:
6 def __init__(self,master,con):
7 self.con = con#pipe connection
8 self.parent = master#Tk執行個體,父容器
9 self.username = ""
10 self.password=""
11 master.protocol("WM_DELETE_WINDOW", self.cancel)#綁定關閉按鈕到cancel函數
12 self.__layout__(master)
13
14 pass
15
16 #布局
17 def __layout__(self,master):
18 master.geometry("320x150+400+100")#視窗大小及坐标
19 master.title("騰Q登陸框")
20
21 row1 = Frame(master)
22 row1.pack(padx=10,pady=15)
23 Label(row1,width=8,text="使用者名:",anchor=W).pack(side=LEFT)
24 self.en_user = Entry(row1)
25 self.en_user.pack(side=LEFT)
26
27 row2 = Frame(master)
28 row2.pack(padx=10,pady=0)
29 Label(row2,width=8,text="密碼:",anchor=W).pack(side=LEFT)
30 self.en_pswd = Entry(row2,show="*")
31 self.en_pswd.pack(side=LEFT)
32
33 row3 = Frame(master)
34 row3.pack(padx=10,pady=15)
35 Button(row3,text="确定",width=10,command=self.ok).pack(side=LEFT,padx=5)
36 Button(row3,text="取消",width=10,command=self.cancel).pack(side=LEFT,padx=5)
37 pass
38
39 def ok(self):
40 self.username = self.en_user.get()
41 self.password = self.en_pswd.get()
42 if not self.validate():
43 print "usrname or password error"
44 return
45 self.con.send({"res":True,"data":(self.username,self.password)})
46 self.parent.quit()
47 self.parent.destroy()
48 pass
49
50 #驗證賬号密碼
51 def validate(self):
52 return True
53
54 def cancel(self):
55 self.con.send({"res":False,"data":(self.username,self.password)})
56 self.parent.quit()
57 self.parent.destroy()
58 pass
效果如圖:
要點四、好友清單
View Code
1 # -*- coding: utf-8 -*-
2 import Tkinter
3 from Tkinter import *
4 from multiprocessing import Process,Pipe
5 from Chat import *
6 import string
7 class Main:
8 def __init__(self,master,con=""):
9 self.con = con # ends of a pipe
10 self.parent = master
11 self.__loadmyself__()
12 self.__layout__(master)
13
14 #在這裡導入個人資料,至少包含name屬性
15 def __loadmyself__(self):
16 self.me = {"name":u"沉魚落雁"}
17 pass
18
19 def __layout__(self,master):
20 master.geometry("320x720+400+0")
21 master.title("騰Q")
22
23 f_message = Frame(master)
24 f_message.pack(fill=X)
25
26 Label(f_message,text=self.me['name']+"(online)").grid(row=0,sticky=W,pady=10,padx=5)
27 Label(f_message,text="好友清單:").grid(row=1,sticky=W)
28
29
30 f_friendlist = Frame(master)
31 f_friendlist.pack(fill=BOTH)
32 #帶滾動條
33 scrollbar = Scrollbar(f_friendlist, orient=VERTICAL)
34
35 self.listbox = Listbox(f_friendlist,yscrollcommand=scrollbar.set,height=700)
36 scrollbar.config(command=self.listbox.yview)
37 scrollbar.pack(side=RIGHT, fill=Y)
38 self.listbox.bind("<Double-Button-1>",self.show)
39 self.refreshfriends()
40 self.listbox.pack(fill=BOTH,expand=1)
41 pass
42
43 #在這裡導入好友清單
44 def loadfriends(self):
45 #reading friends list from server
46 #for example:(needs to be modified)
47 self.friendlist = [{"ID":0,"name":u"xxx","state":"on"},{"ID":1,"name":u"範德薩","state":"off"}]
48
49 fl = self.friendlist
50 for obj in fl:
51 self.listbox.insert(END,"%s(%s)"% (obj["name"],obj["state"]))
52 for i in range(2,50):
53 obj = {"ID":i,"name":u"王老吉%d"%i,"state":"on"}
54 self.friendlist.append(obj)
55 self.listbox.insert(END,"%s(%s)"% (obj["name"],obj["state"]))
56 pass
57
58 #更新好友清單,通常是周期性更新好友狀态
59 def refreshfriends(self):
60 self.listbox.delete(0,END)
61 self.loadfriends()
62 pass
63
64 #開啟對話框
65 def show(self,event):
66 lb = self.listbox;
67 ss = lb.curselection()
68 if len(ss) == 1:
69 #print lb.curselection(),lb.get(lb.curselection())
70 index = string.atoi(ss[0])
71 if index >= len(self.friendlist) :
72 print "error",index,len(self.friendlist)
73 else:
74 obj = self.friendlist[index]
75 if not obj.has_key("open"):
76 self.__openchat__(obj)
77 else:
78 if not obj["open"] == "yes":
79 self.__openchat__(obj)
80 else:
81 print obj['ID']," alreay open"
82 #print self.friendlist[ss[0]]
83 pass
84
85 def __openchat__(self,obj):
86 obj["open"] = "yes"
87 chat = Chat(self.parent,"",obj,self.me)
88 pass
89
90 if __name__ == "__main__":
91 root = Tk()
92 main = Main(root)
93 root.mainloop()
效果如圖:
要點五、對話框基類
View Code
1 # coding=UTF-8
2 # File: myDialog.py
3
4 from Tkinter import *
5 import os
6
7 class Dialog(Toplevel):
8
9 def __init__(self, parent, title = None):
10
11 Toplevel.__init__(self, parent)
12 self.transient(parent)
13
14 if title:
15 self.title(title)
16
17 self.parent = parent
18
19 self.result = None
20
21
22 body = Frame(self)
23 self.initial_focus = self.body(body)
24 body.pack(padx=5, pady=5,fill=X)
25
26 self.buttonbox()
27
28 #self.grab_set()
29
30 if not self.initial_focus:
31 self.initial_focus = self
32
33 self.protocol("WM_DELETE_WINDOW", self.cancel)
34
35 self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
36 parent.winfo_rooty()+50))
37
38 self.initial_focus.focus_set()
39
40 self.wait_window(self)
41
42 #
43 # construction hooks
44
45 def body(self, master):
46 # create dialog body. return widget that should have
47 # initial focus. this method should be overridden
48
49 pass
50
51 def buttonbox(self):
52 # add standard button box. override if you don't want the
53 # standard buttons
54
55 box = Frame(self)
56
57 self.btn_ok = Button(box, text="确定", width=10, command=self.ok)
58 self.btn_ok .pack(side=LEFT, padx=5, pady=5)
59 self.btn_cancel = Button(box, text="取消", width=10, command=self.cancel)
60 self.btn_cancel .pack(side=LEFT, padx=5, pady=5)
61
62 #self.bind("<Return>", self.ok)
63 #self.bind("<Escape>", self.cancel)
64
65 box.pack(anchor=E)
66
67 #
68 # standard button semantics
69
70 def ok(self, event=None):
71
72 if not self.validate():
73 self.initial_focus.focus_set() # put focus back
74 return
75
76 self.withdraw()
77 self.update_idletasks()
78
79 self.apply()
80
81 self.cancel()
82
83 def cancel(self, event=None):
84 # put focus back to the parent window
85 self.parent.focus_set()
86 self.destroy()
87
88 #
89 # command hooks
90
91 def validate(self):
92
93 return 1 # override
94
95 def apply(self):
96
97 pass # override
要點六、對話框
View Code
1 # coding=UTF-8
2 import Tkinter
3 from Tkinter import *
4 from myDialog import *
5 from datetime import *
6
7 class Chat(Dialog):
8 def __init__(self,master,title,obj,me):
9 self.obj = obj
10 self.me = me
11 t = u"與 "+obj['name']+u" 聊天中"
12 Dialog.__init__(self,master,t)
13
14 def apply(self):
15 dt= datetime.now()
16 timestr = u'%s于%s說: \n' % (self.me['name'],dt.strftime('%c'))
17 msg = self.input.get(1.0,END)
18 if msg.strip() == "":
19 return False
20 self.insertmessage(timestr+msg)
21 self.input.delete(1.0,END)
22
23 self.text.yview(MOVETO, 1.0)
24 pass
25
26 def body(self,master):
27 self.geometry("680x480")
28 self.resizable(False,False)
29
30 frame = Frame(master)
31 Label(frame,text="聊天記錄:").pack(padx=5,pady=5)
32 frame.grid(row=0,sticky=W)
33
34 frame = Frame(master)
35 frame.grid(row=1)
36 self.text_scrollbar = Scrollbar(frame, orient=VERTICAL)
37 self.text = Text(frame,yscrollcommand= self.text_scrollbar.set,height=14,bg="white")
38 self.text_scrollbar.config(command=self.text.yview)
39 self.text_scrollbar.pack(side=RIGHT, fill=Y)
40 self.text.bind("<KeyPress>", lambda e : "break")
41 self.text.pack()
42
43 frame = Frame(master)
44 Label(frame,text="輸入聊天資訊:").pack(padx=5,pady=5)
45 frame.grid(row=2,sticky=W)
46
47
48 frame = Frame(master)
49 frame.grid(row=3)
50 scrollbar = Scrollbar(frame, orient=VERTICAL)
51 self.input = Text(frame,yscrollcommand=scrollbar.set,height=8,bg="white")
52 scrollbar.config(command=self.input.yview)
53 scrollbar.pack(side=RIGHT,fill=Y)
54 self.input.pack(fill=Y)
55
56
57 #插入聊天資訊(顯示在聊天框)
58 def insertmessage(self,msg):
59 self.text.insert(END,msg+"\n")
60 pass
61
62 #設定對話框标題
63 def setTitle(self,title):
64 self.title(title)
65 pass
66
67 def ok(self,event=None):
68 self.apply()
69 pass
70
71 def cancel(self,event=None):
72 self.obj["open"] = "no"
73 print "set open %s to no"%self.obj['name']
74 Dialog.cancel(self,event)
75
76 if __name__ == "__main__":
77 print "開放的"
效果如圖:
轉載于:https://www.cnblogs.com/snuby/archive/2013/04/01/2993240.html