python學(xué)習(xí)日記-2016.7.27

1.使用python制作GUI界面

Python支持多種圖形界面的第三方庫(kù)户侥,包括:
a.Tk
b.wxWidgets
c.Qt
d.GTK
等等。
但是Python自帶的庫(kù)是支持Tk的Tkinter池凄,使用Tkinter,無需安裝任何包屿附,就可以直接使用斑芜。本章簡(jiǎn)單介紹如何使用Tkinter進(jìn)行GUI編程。
Tkinter
我們來梳理一下概念:
我們編寫的Python代碼會(huì)調(diào)用內(nèi)置的Tkinter精绎,Tkinter封裝了訪問Tk的接口速缨;Tk是一個(gè)圖形庫(kù),支持多個(gè)操作系統(tǒng)代乃,使用Tcl語(yǔ)言開發(fā)旬牲;Tk會(huì)調(diào)用操作系統(tǒng)提供的本地GUI接口,完成最終的GUI搁吓。所以原茅,我們的代碼只需要調(diào)用Tkinter提供的接口就可以了。
第一個(gè)GUI程序
使用Tkinter十分簡(jiǎn)單堕仔,我們來編寫一個(gè)GUI版本的“Hello, world!”擂橘。第一步是導(dǎo)入Tkinter包的所有內(nèi)容:
from tkinter import *
第二步是從Frame派生一個(gè)Application類,這是所有Widget的父容器:

class Application(Frame): 
  def __init__(self, master=None): 
    Frame.__init__(self, master) 
    self.pack() 
    self.createWidgets() 
  def createWidgets(self): 
    self.helloLabel = Label(self, text='Hello, world!')         
    self.helloLabel.pack() 
    self.quitButton = Button(self, text='Quit', command=self.quit)     
    self.quitButton.pack()

在GUI中贮预,每個(gè)Button贝室、Label契讲、輸入框等,都是一個(gè)Widget滑频。Frame則是可以容納其他Widget的Widget捡偏,所有的Widget組合起來就是一棵樹。
pack()方法把Widget加入到父容器中峡迷,并實(shí)現(xiàn)布局银伟。pack()是最簡(jiǎn)單的布局,grid()可以實(shí)現(xiàn)更復(fù)雜的布局绘搞。在createWidgets()
方法中彤避,我們創(chuàng)建一個(gè)Label和一個(gè)Button,當(dāng)Button被點(diǎn)擊時(shí)夯辖,觸發(fā)self.quit()使程序退出琉预。
第三步,實(shí)例化Application蒿褂,并啟動(dòng)消息循環(huán):

app = Application()
# 設(shè)置窗口標(biāo)題:
app.master.title('Hello World')
# 主消息循環(huán):
app.mainloop()

運(yùn)行結(jié)果如下:

彈窗

輸入文本
我們?cè)賹?duì)這個(gè)GUI程序改進(jìn)一下圆米,加入一個(gè)文本框,讓用戶可以輸入文本啄栓,然后點(diǎn)按鈕后娄帖,彈出消息對(duì)話框。

from tkinter import *
import tkinter.messagebox as messagebox
class Application(Frame): 
  def __init__(self, master=None): 
    Frame.__init__(self, master) 
    self.pack() 
    self.createWidgets() 
  def createWidgets(self): 
    self.nameInput = Entry(self) 
    self.nameInput.pack() 
    self.alertButton = Button(self, text='Hello', command=self.hello) 
    self.alertButton.pack() 
  def hello(self): 
    name = self.nameInput.get() or 'world' 
    messagebox.showinfo('Message', 'Hello, %s' % name)

app = Application()
# 設(shè)置窗口標(biāo)題:
app.master.title('Hello World')
# 主消息循環(huán):
app.mainloop()

當(dāng)用戶點(diǎn)擊按鈕時(shí)昙楚,觸發(fā)hello()近速,通過self.nameInput.get()獲得用戶輸入的文本后,使用tkMessageBox.showinfo()可以彈出消息對(duì)話框堪旧。
程序運(yùn)行結(jié)果如下:

運(yùn)行結(jié)果
運(yùn)行結(jié)果

2.使用基于TCP協(xié)議的socket

要?jiǎng)?chuàng)建一個(gè)基于TCP連接的Socket削葱,可以這樣做:

# 導(dǎo)入socket庫(kù):
import socket
# 創(chuàng)建一個(gè)socket:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立連接:
s.connect(('www.sina.com.cn', 80))

創(chuàng)建Socket時(shí),AF_INET
指定使用IPv4協(xié)議崎场,如果要用更先進(jìn)的IPv6佩耳,就指定為AF_INET6。SOCK_STREAM指定使用面向流的TCP協(xié)議谭跨,這樣干厚,一個(gè)Socket
對(duì)象就創(chuàng)建成功,但是還沒有建立連接螃宙÷椋客戶端要主動(dòng)發(fā)起TCP連接,必須知道服務(wù)器的IP地址和端口號(hào)谆扎。新浪網(wǎng)站的IP地址可以用域名www.sina.com.cn自動(dòng)轉(zhuǎn)換到IP地址挂捅,但是怎么知道新浪服務(wù)器的端口號(hào)呢?答案是作為服務(wù)器堂湖,提供什么樣的服務(wù)闲先,端口號(hào)就必須固定下來状土。由于我們想要訪問網(wǎng)頁(yè),因此新浪提供網(wǎng)頁(yè)服務(wù)的服務(wù)器必須把端口號(hào)固定在80
端口伺糠,因?yàn)?0端口是Web服務(wù)的標(biāo)準(zhǔn)端口蒙谓。其他服務(wù)都有對(duì)應(yīng)的標(biāo)準(zhǔn)端口號(hào),例如SMTP服務(wù)是25端口训桶,F(xiàn)TP服務(wù)是21端口累驮,等等。端口號(hào)小于1024的是Internet標(biāo)準(zhǔn)服務(wù)的端口舵揭,端口號(hào)大于1024的谤专,可以任意使用。
因此午绳,我們連接新浪服務(wù)器的代碼如下:
s.connect(('www.sina.com.cn', 80))
注意參數(shù)是一個(gè)tuple置侍,包含地址和端口號(hào)。建立TCP連接后拦焚,我們就可以向新浪服務(wù)器發(fā)送請(qǐng)求墅垮,要求返回首頁(yè)的內(nèi)容:

# 發(fā)送數(shù)據(jù):
s.send(b'GET / HTTP/1.1\r\nHost: www.sina.com.cn\r\nConnection: close\r\n\r\n')

TCP連接創(chuàng)建的是雙向通道,雙方都可以同時(shí)給對(duì)方發(fā)數(shù)據(jù)耕漱。但是誰(shuí)先發(fā)誰(shuí)后發(fā),怎么協(xié)調(diào)抬伺,要根據(jù)具體的協(xié)議來決定螟够。例如,HTTP協(xié)議規(guī)定客戶端必須先發(fā)請(qǐng)求給服務(wù)器峡钓,服務(wù)器收到后才發(fā)數(shù)據(jù)給客戶端妓笙。
發(fā)送的文本格式必須符合HTTP標(biāo)準(zhǔn),如果格式?jīng)]問題能岩,接下來就可以接收新浪服務(wù)器返回的數(shù)據(jù)了:

# 接收數(shù)據(jù):
buffer = []
while True: 
  # 每次最多接收1k字節(jié): 
  d = s.recv(1024) 
  if d: 
    buffer.append(d) 
  else: 
    break
data = b''.join(buffer)

接收數(shù)據(jù)時(shí)寞宫,調(diào)用recv(max)方法,一次最多接收指定的字節(jié)數(shù)拉鹃,因此辈赋,在一個(gè)while循環(huán)中反復(fù)接收,直到recv()返回空數(shù)據(jù)膏燕,表示接收完畢钥屈,退出循環(huán)。當(dāng)我們接收完數(shù)據(jù)后坝辫,調(diào)用close()方法關(guān)閉Socket篷就,這樣,一次完整的網(wǎng)絡(luò)通信就結(jié)束了:

# 關(guān)閉連接:
s.close()

接收到的數(shù)據(jù)包括HTTP頭和網(wǎng)頁(yè)本身近忙,我們只需要把HTTP頭和網(wǎng)頁(yè)分離一下竭业,把HTTP頭打印出來智润,網(wǎng)頁(yè)內(nèi)容保存到文件:

header, html = data.split(b'\r\n\r\n', 1)
print(header.decode('utf-8'))
# 把接收的數(shù)據(jù)寫入文件:
with open('sina.html', 'wb') as f: 
  f.write(html)

現(xiàn)在,只需要在瀏覽器中打開這個(gè)sina.html文件未辆,就可以看到新浪的首頁(yè)了窟绷。

3.使用sqlite3

SQLite是一種嵌入式數(shù)據(jù)庫(kù),它的數(shù)據(jù)庫(kù)就是一個(gè)文件鼎姐。由于SQLite本身是C寫的钾麸,而且體積很小,所以炕桨,經(jīng)常被集成到各種應(yīng)用程序中饭尝,甚至在iOS和Android的App中都可以集成。
Python就內(nèi)置了SQLite3献宫,所以钥平,在Python中使用SQLite,不需要安裝任何東西姊途,直接使用涉瘾。
在使用SQLite前,我們先要搞清楚幾個(gè)概念:
表是數(shù)據(jù)庫(kù)中存放關(guān)系數(shù)據(jù)的集合捷兰,一個(gè)數(shù)據(jù)庫(kù)里面通常都包含多個(gè)表立叛,比如學(xué)生的表,班級(jí)的表贡茅,學(xué)校的表秘蛇,等等。表和表之間通過外鍵關(guān)聯(lián)顶考。
要操作關(guān)系數(shù)據(jù)庫(kù)赁还,首先需要連接到數(shù)據(jù)庫(kù),一個(gè)數(shù)據(jù)庫(kù)連接稱為Connection驹沿;
連接到數(shù)據(jù)庫(kù)后艘策,需要打開游標(biāo),稱之為Cursor渊季,通過Cursor執(zhí)行SQL語(yǔ)句朋蔫,然后,獲得執(zhí)行結(jié)果梭域。
Python定義了一套操作數(shù)據(jù)庫(kù)的API接口斑举,任何數(shù)據(jù)庫(kù)要連接到Python,只需要提供符合Python標(biāo)準(zhǔn)的數(shù)據(jù)庫(kù)驅(qū)動(dòng)即可病涨。
由于SQLite的驅(qū)動(dòng)內(nèi)置在Python標(biāo)準(zhǔn)庫(kù)中富玷,所以我們可以直接來操作SQLite數(shù)據(jù)庫(kù)。
我們?cè)赑ython交互式命令行實(shí)踐一下:

# 導(dǎo)入SQLite驅(qū)動(dòng):
>>> import sqlite3
# 連接到SQLite數(shù)據(jù)庫(kù)# 數(shù)據(jù)庫(kù)文件是test.db
# 如果文件不存在,會(huì)自動(dòng)在當(dāng)前目錄創(chuàng)建:
>>> conn = sqlite3.connect('test.db')
# 創(chuàng)建一個(gè)Cursor:
>>> cursor = conn.cursor()
# 執(zhí)行一條SQL語(yǔ)句赎懦,創(chuàng)建user表:
>>> cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')
<sqlite3.Cursor object at 0x10f8aa260>
# 繼續(xù)執(zhí)行一條SQL語(yǔ)句雀鹃,插入一條記錄:
>>> cursor.execute('insert into user (id, name) values (\'1\', \'Michael\')')
<sqlite3.Cursor object at 0x10f8aa260>
# 通過rowcount獲得插入的行數(shù):
>>> cursor.rowcount
1
# 關(guān)閉Cursor:
>>> cursor.close()
# 提交事務(wù):
>>> conn.commit()
# 關(guān)閉Connection:
>>> conn.close()

我們?cè)僭囋嚥樵冇涗洠?/p>

>>> conn = sqlite3.connect('test.db')
>>> cursor = conn.cursor()
# 執(zhí)行查詢語(yǔ)句:
>>> cursor.execute('select * from user where id=?', ('1',))
<sqlite3.Cursor object at 0x10f8aa340>
# 獲得查詢結(jié)果集:
>>> values = cursor.fetchall()
>>> values[('1', 'Michael')]
>>> cursor.close()
>>> conn.close()

使用Python的DB-API時(shí),只要搞清楚Connection和Cursor對(duì)象励两,打開后一定記得關(guān)閉黎茎,就可以放心地使用。使用Cursor對(duì)象執(zhí)行insert当悔,update傅瞻,delete語(yǔ)句時(shí),執(zhí)行結(jié)果由rowcount返回影響的行數(shù)盲憎,就可以拿到執(zhí)行結(jié)果嗅骄。使用Cursor對(duì)象執(zhí)行select語(yǔ)句時(shí),通過featchall()可以拿到結(jié)果集饼疙。結(jié)果集是一個(gè)list溺森,每個(gè)元素都是一個(gè)tuple,對(duì)應(yīng)一行記錄窑眯。
如果SQL語(yǔ)句帶有參數(shù)屏积,那么需要把參數(shù)按照位置傳遞給execute()
方法,有幾個(gè)?占位符就必須對(duì)應(yīng)幾個(gè)參數(shù)磅甩,例如:

cursor.execute('select * from user where name=? and pwd=?', ('abc', 'password'))

SQLite支持常見的標(biāo)準(zhǔn)SQL語(yǔ)句以及幾種常見的數(shù)據(jù)類型炊林。具體文檔請(qǐng)參閱SQLite官方網(wǎng)站。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末卷要,一起剝皮案震驚了整個(gè)濱河市铛铁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌却妨,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件括眠,死亡現(xiàn)場(chǎng)離奇詭異彪标,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)掷豺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門捞烟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人当船,你說我怎么就攤上這事题画。” “怎么了德频?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵苍息,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng)竞思,這世上最難降的妖魔是什么表谊? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮盖喷,結(jié)果婚禮上爆办,老公的妹妹穿的比我還像新娘。我一直安慰自己课梳,他們只是感情好距辆,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暮刃,像睡著了一般跨算。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上沾歪,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天漂彤,我揣著相機(jī)與錄音,去河邊找鬼灾搏。 笑死挫望,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的狂窑。 我是一名探鬼主播媳板,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼泉哈!你這毒婦竟也來了蛉幸?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤丛晦,失蹤者是張志新(化名)和其女友劉穎奕纫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烫沙,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年锌蓄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了升筏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡瘸爽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出剪决,到底是詐尸還是另有隱情灵汪,我是刑警寧澤檀训,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站识虚,受9級(jí)特大地震影響肢扯,放射性物質(zhì)發(fā)生泄漏担锤。R本人自食惡果不足惜蔚晨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一肛循、第九天 我趴在偏房一處隱蔽的房頂上張望铭腕。 院中可真熱鬧,春花似錦多糠、人聲如沸累舷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)被盈。三九已至,卻和暖如春搭伤,著一層夾襖步出監(jiān)牢的瞬間只怎,已是汗流浹背怜俐。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拍鲤,地道東北人贴谎。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓季稳,卻偏偏與公主長(zhǎng)得像擅这,于是被迫代替她去往敵國(guó)和親景鼠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蕾哟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    aimaile閱讀 26,504評(píng)論 6 427
  • 環(huán)境管理管理Python版本和環(huán)境的工具莲蜘。p–非常簡(jiǎn)單的交互式python版本管理工具帘营。pyenv–簡(jiǎn)單的Pyth...
    MrHamster閱讀 3,798評(píng)論 1 61
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,332評(píng)論 25 707
  • 按說現(xiàn)在的教育基礎(chǔ)設(shè)施和師資力量也相對(duì)前十年特別充足了,學(xué)外語(yǔ)也變成了很習(xí)以為常的事情芬迄。但是據(jù)我這幾年的發(fā)現(xiàn)...
    無心傾城閱讀 1,170評(píng)論 5 2
  • 我有多久沒試過杜窄,因?yàn)橐皇赘瓒鴾I流滿面了? 意識(shí)到這個(gè)問題的時(shí)候塞耕,我的老師剛耳提面命地教我蚀腿,要有豐富的情感扫外,你的音樂...
    Hokcho閱讀 246評(píng)論 0 0