(八)Python 圖形化界面設(shè)計(jì)

  • 1、圖形化界面設(shè)計(jì)的基本理解

    當(dāng)前流行的計(jì)算機(jī)桌面應(yīng)用程序大多數(shù)為圖形化用戶界面(Graphic User Interface,GUI),即通過鼠標(biāo)對(duì)菜單、按鈕等圖形化元素觸發(fā)指令,并從標(biāo)簽、對(duì)話框等圖型化顯示容器中獲取人機(jī)對(duì)話信息。
    Python自帶了tkinter 模塊,實(shí)質(zhì)上是一種流行的面向?qū)ο蟮腉UI工具包 TK 的Python編程接口,提供了快速便利地創(chuàng)建GUI應(yīng)用程序的方法。其圖像化編程的基本步驟通常包括:

    • 導(dǎo)入 tkinter 模塊
    • 創(chuàng)建 GUI 根窗體
    • 添加人機(jī)交互控件并編寫相應(yīng)的函數(shù)。
    • 在主事件循環(huán)中等待用戶觸發(fā)事件響應(yīng)。
  • 2、窗體控件布局

    • 2.1、根窗體是圖像化應(yīng)用程序的根控制器,是tkinter的底層控件的實(shí)例。當(dāng)導(dǎo)入tkinter模塊后,調(diào)用 Tk()方法可初始化一個(gè)根窗體實(shí)例 root ,用 title() 方法可設(shè)置其標(biāo)題文字,用geometry()方法可以設(shè)置窗體的大?。ㄒ韵袼貫閱挝唬?。將其置于主循環(huán)中,除非用戶關(guān)閉,否則程序始終處于運(yùn)行狀態(tài)。執(zhí)行該程序,一個(gè)窗體就呈現(xiàn)出來(lái)了。在這個(gè)主循環(huán)的根窗體中,可持續(xù)呈現(xiàn)中的其他可視化控件實(shí)例,監(jiān)測(cè)事件的發(fā)生并執(zhí)行相應(yīng)的處理程序。下面是根窗體呈現(xiàn)示例:

      from tkinter import *
      root= Tk()
      root.title('我的第一個(gè)Python窗體')
      root.geometry('240x240') # 這里的乘號(hào)不是 * ,而是小寫英文字母 x
      root.mainloop()
      
      根窗體呈現(xiàn)示例
    • 2.2、tkinter 常用控件

      • 常用控件:常用的10 多種,如下:
      控件 名稱 作用
      Button 按鈕 單擊觸發(fā)事件
      Canvas 畫布 繪制圖形或繪制特殊控件
      Checkbutton 復(fù)選框 多項(xiàng)選擇
      Entry 輸入框 接收單行文本輸入
      Frame 框架 用于控件分組
      Label 標(biāo)簽 單行文本顯示
      Lisbox 列表框 顯示文本列表
      Menu 菜單 創(chuàng)建菜單命令
      Message 消息 多行文本標(biāo)簽,與Label 用法類似
      Radiobutton 單選按鈕 從互斥的多個(gè)選項(xiàng)中做單項(xiàng)選擇
      Scale 滑塊 默認(rèn)垂直方向,鼠標(biāo)拖動(dòng)改變數(shù)值形成可視化交互
      Scrollbar 滑動(dòng)條 默認(rèn)垂直方向,課鼠標(biāo)拖動(dòng)改變數(shù)值,可與 Text、Lisbox、Canvas等控件配合移動(dòng)可視化空間
      Text 文本框 接收或輸出顯示多行文本
      Toplevel 新建窗體容器 在頂層創(chuàng)建新窗體
      • 控件的共同屬性:在窗體上呈現(xiàn)的可視化控件,通常包括尺寸、顏色、字體、相對(duì)位置、浮雕樣式、圖標(biāo)樣式和懸停光標(biāo)形狀等共同屬性。不同的控件由于形狀和功能不同,又有其特征屬性。在初始化根窗體和根窗體主循環(huán)之間,可實(shí)例化窗體控件,并設(shè)置其屬性。父容器可為根窗體或其他容器控件實(shí)例。常見的控件共同屬性如下表:

        屬性 說明 取值
        anchor 文本起始位置 CENTER(默認(rèn)),E,S,W,N,NE,SE,SW,NW
        bg 背景色 無(wú)
        bd 加粗(默認(rèn) 2 像素) 無(wú)
        bitmap 黑白二值圖標(biāo) 網(wǎng)上查找
        cursor 鼠標(biāo)懸停光標(biāo) 網(wǎng)上查找
        font 字體 無(wú)
        fg 前景色 無(wú)
        height 高(文本控件的單位為行,不是像素) 無(wú)
        image 顯示圖像 無(wú)
        justify 多行文本的對(duì)其方式 CENTER(默認(rèn)),LEFT,RIGHT,TOP,BOTTOM
        padx 水平擴(kuò)展像素 無(wú)
        pady 垂直擴(kuò)展像素 無(wú)
        relief 3D浮雕樣式 FLAT,RAISED,SUNKEN,GROOVE,RIDGE
        state 控件實(shí)例狀態(tài)是否可用 NORMAL(默認(rèn)),DISABLED
        width 寬(文本控件的單位為行,不是像素) 無(wú)

        標(biāo)簽及常見屬性示例:

        from  tkinter import *
        root = Tk()
        lb = Label(root,text='我是第一個(gè)標(biāo)簽',\
                bg='#d3fbfb',\
                fg='red',\
                font=('華文新魏',32),\
                width=20,\
                height=2,\
                relief=SUNKEN)
        lb.pack()
        root.mainloop()
        


        其中,標(biāo)簽實(shí)例lb 在父容器root中實(shí)例化,具有代碼中所示的text(文本)、bg(背景色)、fg(前景色)、font(字體)、width(寬,默認(rèn)以字符為單位)、height(高,默認(rèn)以字符為單位)和 relief(浮雕樣式)等一系列屬性。
        在實(shí)例化控件時(shí),實(shí)例的屬性可以“屬性=屬性值”的形式枚舉列出,不區(qū)分先后次序。例如:“ text='我是第一個(gè)標(biāo)簽' ”顯示標(biāo)簽的文本內(nèi)容,“bg='#d3fbfb'”設(shè)置背景色為十六進(jìn)制數(shù)RGB色 #d3fbfb等等。屬性值通常用文本形式表示。
        當(dāng)然如果這個(gè)控件實(shí)例只需要一次性呈現(xiàn),也可以不必命名,直接實(shí)例化并布局呈現(xiàn)出來(lái),例如:

        Label(root,text='我是第一個(gè)標(biāo)簽',font='華文新魏').pack()
        

屬性 relief 為控件呈現(xiàn)出來(lái)的3D浮雕樣式,有 FLAT(平的)、RAISED(凸起的)、SUNKEN(凹陷的)、GROOVE(溝槽狀邊緣)和 RIDGE(脊?fàn)钸吘? 5種。


控件呈現(xiàn)的5種浮雕樣式
  • 2.2、控件布局
    控件的布局通常有pack()、grid()place() 三種方法。

    • 2.2.1、pack()方法:是一種簡(jiǎn)單的布局方法,如果不加參數(shù)的默認(rèn)方式,將按布局語(yǔ)句的先后,以最小占用空間的方式自上而下地排列控件實(shí)例,并且保持控件本身的最小尺寸。如下的例子:

      • 用pack() 方法不加參數(shù)排列標(biāo)簽。為看清楚各控件所占用的空間大小,文本用了不同長(zhǎng)度的中英文,并設(shè)置relief=GROOVE的凹陷邊緣屬性。如下所示:
        from tkinter import  *
        root = Tk()
        
        lbred = Label(root,text="Red",fg="Red",relief=GROOVE)
        lbred.pack()
        lbgreen = Label(root,text="綠色",fg="green",relief=GROOVE)
        lbgreen.pack()
        lbblue = Label(root,text="藍(lán)",fg="blue",relief=GROOVE)
        lbblue.pack()
        root.mainloop()
        
      • 使用pack()方法可設(shè)置 fill、side 等屬性參數(shù)。其中,參數(shù)fill 可取值:fill=X,fill=Y或fill=BOTH,分別表示允許控件向水平方向、垂直方向或二維伸展填充未被占用控件。參數(shù) side 可取值:side=TOP(默認(rèn)),side=LEFT,side=RIGHT,side=BOTTOM,分別表示本控件實(shí)例的布局相對(duì)于下一個(gè)控件實(shí)例的方位。如下例子:


        用pack()方法加參數(shù)排列標(biāo)簽
        from tkinter import  *
        root = Tk()
        
        lbred = Label(root,text="Red",fg="Red",relief=GROOVE)
        lbred.pack()
        lbgreen = Label(root,text="綠色",fg="green",relief=GROOVE)
        lbgreen.pack(side=RIGHT)
        lbblue = Label(root,text="藍(lán)",fg="blue",relief=GROOVE)
        lbblue.pack(fill=X)
        root.mainloop()
        
    • 2.2.2、grid()方法:是基于網(wǎng)格的布局。先虛擬一個(gè)二維表格,再在該表格中布局控件實(shí)例。由于在虛擬表格的單元中所布局的控件實(shí)例大小不一,單元格也沒有固定或均一的大小,因此其僅用于布局的定位。pack()方法與grid()方法不能混合使用。
      grid()方法常用布局參數(shù)如下:

      • column: 控件實(shí)例的起始列,最左邊為第0列。
      • columnspan: 控件實(shí)例所跨越的列數(shù),默認(rèn)為1列。
      • ipadx,ipady: 控件實(shí)例所呈現(xiàn)區(qū)域內(nèi)部的像素?cái)?shù),用來(lái)設(shè)置控件實(shí)例的大小。
      • padx,pady: 控件實(shí)例所占據(jù)空間像素?cái)?shù),用來(lái)設(shè)置實(shí)例所在單元格的大小。
      • row: 控件實(shí)例的起始行,最上面為第0行。
      • rowspan: 控件實(shí)例的起始行數(shù),默認(rèn)為1行。

      看下面的例子:用grid()方法排列標(biāo)簽,設(shè)想有一個(gè)3x4的表格,起始行、列序號(hào)均為0.將標(biāo)簽lbred 至于第2列第0行;將標(biāo)簽lbgreen置于第0列第1行;將標(biāo)簽lbblue置于第1列起跨2列第2行,占20像素寬。


      pack()方法排列標(biāo)簽
      from tkinter import  *
      root = Tk()
      
      lbred = Label(root,text="Red",fg="Red",relief=GROOVE)
      lbred.grid(column=2,row=0)
      lbgreen = Label(root,text="綠色",fg="green",relief=GROOVE)
      lbgreen.grid(column=0,row=1)
      lbblue = Label(root,text="藍(lán)",fg="blue",relief=GROOVE)
      lbblue.grid(column=1,columnspan=2,ipadx=20,row=2)
      root.mainloop()
      
    • 2.2.3、place()方法:根據(jù)控件實(shí)例在父容器中的絕對(duì)或相對(duì)位置參數(shù)進(jìn)行布局。其常用布局參數(shù)如下:

      • x,y:控件實(shí)例在根窗體中水平和垂直方向上的其實(shí)位置(單位為像素)。注意,根窗體左上角為0,0,水平向右,垂直向下為正方向。

      • relx,rely:控件實(shí)例在根窗體中水平和垂直方向上起始布局的相對(duì)位置。即相對(duì)于根窗體寬和高的比例位置,取值在0.0~1.0之間。

      • height,width:控件實(shí)例本身的高度和寬度(單位為像素)。

      • relheight,relwidth:控件實(shí)例相對(duì)于根窗體的高度和寬度比例,取值在0.0~1.0之間。

      • 利用place()方法配合relx,rely和relheight,relwidth參數(shù)所得的到的界面可自適應(yīng)根窗體尺寸的大小。place()方法與grid()方法可以混合使用。如下例子:利用place()方法排列消息(多行標(biāo)簽)。


        place()方法排列消息
        from tkinter import *
        root = Tk()
        root.geometry('320x240')
        
        msg1 = Message(root,text='''我的水平起始位置相對(duì)窗體 0.2,垂直起始位置為絕對(duì)位置 80 像素,我的高度是窗體高度的0.4,寬度是200像素''',relief=GROOVE)
        msg1.place(relx=0.2,y=80,relheight=0.4,width=200)
        root.mainloop()
        
  • 3、tkinter常見控件的特征屬性

    • 3.1、文本輸入和輸出相關(guān)控件:文本的輸入與輸出控件通常包括:標(biāo)簽(Label)、消息(Message)、輸入框(Entry)、文本框(Text)。他們除了前述共同屬性外,都具有一些特征屬性和功能。

      • 標(biāo)簽(Label)和 消息(Message):除了單行與多行的不同外,屬性和用法基本一致,用于呈現(xiàn)文本信息。值得注意的是:屬性text通常用于實(shí)例在第一次呈現(xiàn)時(shí)的固定文本,而如果需要在程序執(zhí)行后發(fā)生變化,則可以使用下列方法之一實(shí)現(xiàn):1、用控件實(shí)例的configure()方法來(lái)改變屬性text的值,可使顯示的文本發(fā)生變化;2、先定義一個(gè)tkinter的內(nèi)部類型變量var=StringVar() 的值也可以使顯示文本發(fā)生變化。
        看下面的一個(gè)例子:制作一個(gè)電子時(shí)鐘,用root的after()方法每隔1秒time模塊以獲取系統(tǒng)當(dāng)前時(shí)間,并在標(biāo)簽中顯示出來(lái)。

        • 方法一:利用configure()方法或config()來(lái)實(shí)現(xiàn)文本變化。


          import tkinter
          import time
          
          def gettime():
                timestr = time.strftime("%H:%M:%S") # 獲取當(dāng)前的時(shí)間并轉(zhuǎn)化為字符串
                lb.configure(text=timestr)   # 重新設(shè)置標(biāo)簽文本
                root.after(1000,gettime) # 每隔1s調(diào)用函數(shù) gettime 自身獲取時(shí)間
          
          root = tkinter.Tk()
          root.title('時(shí)鐘')
          
          lb = tkinter.Label(root,text='',fg='blue',font=("黑體",80))
          lb.pack()
          gettime()
          root.mainloop()
          
        • 方法二:利用textvariable變量屬性來(lái)實(shí)現(xiàn)文本變化。

          import tkinter
          import time
          
          def gettime():
                var.set(time.strftime("%H:%M:%S"))   # 獲取當(dāng)前時(shí)間
                root.after(1000,gettime)   # 每隔1s調(diào)用函數(shù) gettime 自身獲取時(shí)間
          
          root = tkinter.Tk()
          root.title('時(shí)鐘')
          var=tkinter.StringVar()
          
          lb = tkinter.Label(root,textvariable=var,fg='blue',font=("黑體",80))
          lb.pack()
          gettime()
          root.mainloop()
          
      • 文本框(Text)

        文本框的常用方法如下:

        方法 功能
        delete(起始位置,[,終止位置]) 刪除指定區(qū)域文本
        get(起始位置,[,終止位置]) 獲取指定區(qū)域文本
        insert(位置,[,字符串]...) 將文本插入到指定位置
        see(位置) 在指定位置是否可見文本,返回布爾值
        index(標(biāo)記) 返回標(biāo)記所在的行和列
        mark_names() 返回所有標(biāo)記名稱
        mark_set(標(biāo)記,位置) 在指定位置設(shè)置標(biāo)記
        mark_unset(標(biāo)記) 去除標(biāo)記

        上表位置的取值可為整數(shù),浮點(diǎn)數(shù)或END(末尾),例如0.0表示第0列第0行
        如下一個(gè)例子:每隔1秒獲取一次當(dāng)前日期的時(shí)間,并寫入文本框中,如下:本例中調(diào)用 datetime.now()獲取當(dāng)前日期時(shí)間,用insert()方法每次從文本框txt的尾部(END)開始追加文本。

        獲取當(dāng)前日期的時(shí)間并寫入文本中

        from tkinter import *
        import time
        import datetime
        
        def gettime():
               s=str(datetime.datetime.now())+'\n'
               txt.insert(END,s)
               root.after(1000,gettime)  # 每隔1s調(diào)用函數(shù) gettime 自身獲取時(shí)間
        
        root=Tk()
        root.geometry('320x240')
        txt=Text(root)
        txt.pack()
        gettime()
        root.mainloop()
        
      • 輸入框(Entry):通常作為功能比較單一的接收單行文本輸入的控件,雖然也有許多對(duì)其中文本進(jìn)行操作的方法,但通常用的只有取值方法get()和用于刪除文本的delete(起始位置,終止位置),例如:清空輸入框?yàn)閐elete(0,END)。

    • 3.2、按鈕(Button):主要是為響應(yīng)鼠標(biāo)單擊事件觸發(fā)運(yùn)行程序所設(shè)的,故其除控件共有屬性外,屬性command是最為重要的屬性。通常,將按鈕要觸發(fā)執(zhí)行的程序以函數(shù)形式預(yù)先定義,然后可以用一下兩種方法調(diào)用函數(shù)。Button按鈕的狀態(tài)有:'normal','active','disabled'

      • 直接調(diào)用函數(shù)。參數(shù)表達(dá)式為“command=函數(shù)名”,注意函數(shù)名后面不要加括號(hào),也不能傳遞參數(shù)。如下面的command=run1:

      • 利用匿名函數(shù)調(diào)用函數(shù)和傳遞參數(shù)。參數(shù)的表達(dá)式為“command=lambda”:函數(shù)名(參數(shù)列表)。例如下面的:"command=lambda:run2(inp1.get(),inp2.get())"。

      • 看下面的例子:1.從兩個(gè)輸入框去的輸入文本后轉(zhuǎn)為浮點(diǎn)數(shù)值進(jìn)行加法運(yùn)算,要求每次單擊按鈕產(chǎn)生的算是結(jié)果以文本的形式追加到文本框中,將原輸入框清空。2.按鈕方法一不傳參數(shù)調(diào)用函數(shù)run1()實(shí)現(xiàn),按鈕“方法二”用lambda調(diào)用函數(shù)run2(x,y)同時(shí)傳遞參數(shù)實(shí)現(xiàn)。


        簡(jiǎn)單加法器
        from tkinter import *
        
        def run1():
             a = float(inp1.get())
             b = float(inp2.get())
             s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b)
             txt.insert(END, s)   # 追加顯示運(yùn)算結(jié)果
             inp1.delete(0, END)  # 清空輸入
             inp2.delete(0, END)  # 清空輸入
        
        def run2(x, y):
             a = float(x)
             b = float(y)
             s = '%0.2f+%0.2f=%0.2f\n' % (a, b, a + b)
             txt.insert(END, s)   # 追加顯示運(yùn)算結(jié)果
             inp1.delete(0, END)  # 清空輸入
             inp2.delete(0, END)  # 清空輸入
        
        root = Tk()
        root.geometry('460x240')
        root.title('簡(jiǎn)單加法器')
        
        lb1 = Label(root, text='請(qǐng)輸入兩個(gè)數(shù),按下面兩個(gè)按鈕之一進(jìn)行加法計(jì)算')
        lb1.place(relx=0.1, rely=0.1, relwidth=0.8, relheight=0.1)
        inp1 = Entry(root)
        inp1.place(relx=0.1, rely=0.2, relwidth=0.3, relheight=0.1)
        inp2 = Entry(root)
        inp2.place(relx=0.6, rely=0.2, relwidth=0.3, relheight=0.1)
        
        # 方法-直接調(diào)用 run1()
        btn1 = Button(root, text='方法一', command=run1)
        btn1.place(relx=0.1, rely=0.4, relwidth=0.3, relheight=0.1)
        
        # 方法二利用 lambda 傳參數(shù)調(diào)用run2()
        btn2 = Button(root, text='方法二', command=lambda: run2(inp1.get(), inp2.get()))
        btn2.place(relx=0.6, rely=0.4, relwidth=0.3, relheight=0.1)
        
        # 在窗體垂直自上而下位置60%處起,布局相對(duì)窗體高度40%高的文本框
        txt = Text(root)
        txt.place(rely=0.6, relheight=0.4)
        
        root.mainloop()
        
    • 3.3、單選按鈕:(Radiobutton)是為了響應(yīng)故鄉(xiāng)排斥的若干單選項(xiàng)的單擊事件以觸發(fā)運(yùn)行自定義函數(shù)所設(shè)的,該控件排除具有共有屬性外,還具有顯示文本(text)、返回變量(variable)、返回值(value)、響應(yīng)函數(shù)名(command)等重要屬性。響應(yīng)函數(shù)名“command=函數(shù)名”的用法與Button相同,函數(shù)名最后也要加括號(hào)。返回變量variable=var通常應(yīng)預(yù)先聲明變量的類型var=IntVar()或var=StringVar(),在所調(diào)用的函數(shù)中方可用var.get()方法獲取被選中實(shí)例的value值。例如下面:

      單選按鈕

      from tkinter import *
      def Mysel():
            dic = {0:'甲',1:'乙',2:'丙'}
            s = "您選了" + dic.get(var.get()) + "項(xiàng)"
            lb.config(text = s)
      
      root = Tk()
      root.title('單選按鈕')
      lb = Label(root)
      lb.pack()
      
      var = IntVar()
      rd1 = Radiobutton(root,text="甲",variable=var,value=0,command=Mysel)
      rd1.pack()
      
      rd2 = Radiobutton(root,text="乙",variable=var,value=1,command=Mysel)
      rd2.pack()
      
      rd3 = Radiobutton(root,text="丙",variable=var,value=2,command=Mysel)
      rd3.pack()
      
      root.mainloop()
      
    • 3.4、復(fù)選框:(Checkbutton) 是為了返回多個(gè)選項(xiàng)值的交互控件,通常不直接觸發(fā)函數(shù)的執(zhí)行。該控件除具有共有屬性外,還具有顯示文本(text)、返回變量(variable)、選中返回值(onvalue)和未選中默認(rèn)返回值(offvalue)等重要屬性。返回變量variable=var 通??梢灶A(yù)先逐項(xiàng)分別聲明變量的類型var=IntVar() (默認(rèn))或 var=StringVar(), 在所調(diào)用的函數(shù)中方可分別調(diào)用 var.get()方法 取得被選中實(shí)例的 onvalue或offvalue值。復(fù)選框?qū)嵗ǔ_€可分別利用 select()、deselect()和 toggle() 方法對(duì)其進(jìn)行選中、清除選中和反選操作。

      • 如下的例子: 利用復(fù)選框?qū)崿F(xiàn),單擊OK,可以將選中的結(jié)果顯示在標(biāo)簽上。效果如下:


        復(fù)選框的應(yīng)用
        • 方法:利用函數(shù)中的 if-else 分支實(shí)現(xiàn)多項(xiàng)顯示

          from tkinter import *
          import tkinter
          
          def run():
               if(CheckVar1.get()==0 and CheckVar2.get()==0 and CheckVar3.get()==0 and CheckVar4.get()==0):
                   s = '您還沒選擇任何愛好項(xiàng)目'
               else:
                   s1 = "足球" if CheckVar1.get()==1 else ""
                   s2 = "籃球" if CheckVar2.get() == 1 else ""
                   s3 = "游泳" if CheckVar3.get() == 1 else ""
                   s4 = "田徑" if CheckVar4.get() == 1 else ""
                   s = "您選擇了%s %s %s %s" % (s1,s2,s3,s4)
               lb2.config(text=s)
          
          root = tkinter.Tk()
          root.title('復(fù)選框')
          lb1=Label(root,text='請(qǐng)選擇您的愛好項(xiàng)目')
          lb1.pack()
          
          CheckVar1 = IntVar()
          CheckVar2 = IntVar()
          CheckVar3 = IntVar()
          CheckVar4 = IntVar()
          
          ch1 = Checkbutton(root,text='足球',variable = CheckVar1,onvalue=1,offvalue=0)
          ch2 = Checkbutton(root,text='籃球',variable = CheckVar2,onvalue=1,offvalue=0)
          ch3 = Checkbutton(root,text='游泳',variable = CheckVar3,onvalue=1,offvalue=0)
          ch4 = Checkbutton(root,text='田徑',variable = CheckVar4,onvalue=1,offvalue=0)
          
          ch1.pack()
          ch2.pack()
          ch3.pack()
          ch4.pack()
          
          btn = Button(root,text="OK",command=run)
          btn.pack()
          
          lb2 = Label(root,text='')
          lb2.pack()
          root.mainloop()
          
    • 3.5、列表框 與 組合框

      • 3.5.1、列表框:(Listbox) 可供用戶單選或多選所列條目以形成人機(jī)交互。列表框控件的主要方法見下面的表:
      方法 功能描述
      curselection() 返回光標(biāo)選中項(xiàng)目編號(hào)的元組,注意并不是單個(gè)的整數(shù)
      delete(起始位置,終止位置) 刪除項(xiàng)目,終止位置可省略,全部清空為delete(0,END)
      get(起始位置,終止位) 返回范圍所含項(xiàng)目文本的元組,終止位置可忽略
      insert(位置,項(xiàng)目元素) 插入項(xiàng)目元素(若有多項(xiàng),可用列表或元組類型賦值),若位置為END,則將項(xiàng)目元素添加在最后
      size() 返回列表框行數(shù)

      執(zhí)行自定義函數(shù)時(shí),通常使用“實(shí)例名.surselection()” 或 “selected” 來(lái)獲取選中項(xiàng)的位置索引。由于列表框?qū)嵸|(zhì)上就是將Python 的列表類型數(shù)據(jù)可視化呈現(xiàn),在程序?qū)崿F(xiàn)時(shí),也可直接對(duì)相關(guān)列表數(shù)據(jù)進(jìn)行操作,然后再通過列表框展示出來(lái),而不必拘泥于可視化控件的方法??聪旅娴囊粋€(gè)例子:實(shí)現(xiàn)列表框的初始化、添加、插入、修改、刪除和清空操作,如下:

      列表框的應(yīng)用

      from tkinter import *
      def ini():
            Lstbox1.delete(0,END)
            list_items = ["數(shù)學(xué)","物理","化學(xué)","語(yǔ)文","外語(yǔ)"]
            for item in list_items:
                 Lstbox1.insert(END,item)
      
      def clear():
            Lstbox1.delete(0,END)
      
      def ins():
            if entry.get() != '':
                if Lstbox1.curselection() == ():
                    Lstbox1.insert(Lstbox1.size(),entry.get())
                else:
                    Lstbox1.insert(Lstbox1.curselection(),entry.get())
      
      def updt():
            if entry.get() != '' and Lstbox1.curselection() != ():
                 selected=Lstbox1.curselection()[0]
                 Lstbox1.delete(selected)
                 Lstbox1.insert(selected,entry.get())
      
      def delt():
            if Lstbox1.curselection() != ():
                 Lstbox1.delete(Lstbox1.curselection())
      
      root = Tk()
      root.title('列表框?qū)嶒?yàn)')
      root.geometry('320x240')
      
      frame1 = Frame(root,relief=RAISED)
      frame1.place(relx=0.0)
      
      frame2 = Frame(root,relief=GROOVE)
      frame2.place(relx=0.5)
      
      Lstbox1 = Listbox(frame1)
      Lstbox1.pack()
      
      entry = Entry(frame2)
      entry.pack()
      
      btn1 = Button(frame2,text='初始化',command=ini)
      btn1.pack(fill=X)
      
      btn2 = Button(frame2,text='添加',command=ins)
      btn2.pack(fill=X)
      
      btn3 = Button(frame2,text='插入',command=ins) # 添加和插入功能實(shí)質(zhì)上是一樣的
      btn3.pack(fill=X)
      
      btn4 = Button(frame2,text='修改',command=updt)
      btn4.pack(fill=X)
      
      btn5 = Button(frame2,text='刪除',command=delt)
      btn5.pack(fill=X)
      
      btn6 = Button(frame2,text='清空',command=clear)
      btn6.pack(fill=X)
      
      root.mainloop()
      
      • 3.5.2、組合框:(Combobox) 實(shí)質(zhì)上是帶文本框的上拉列表框,其功能也將是Python 的列表類型數(shù)據(jù)可視化呈現(xiàn),并提供用戶單選或多選所列條目以形成人機(jī)交互。在圖形化界面設(shè)計(jì)時(shí),由于其具有靈活的界面,因此往往比列表框更受喜愛。但該控件并不包含在 tkinter 模塊中,而是與 TreeView、Progressbar、Separator等控件一同包含在tkinter 的子模塊ttk中。如果使用該控件,應(yīng)先與from tkinter import ttk 語(yǔ)句引用ttk子模塊,然后創(chuàng)建組合框?qū)嵗?實(shí)例名=Combobox(根對(duì)象,[屬性列表])
        指定變量var=StringVar(),并設(shè)置實(shí)例屬性 textvariable = var,values=[列表...]。組合框控件常用方法有:獲得所選中的選項(xiàng)值get()和獲得所選中的選項(xiàng)索引current()。
        看下面的一個(gè)例子:實(shí)現(xiàn)四則運(yùn)算計(jì)算器,將兩個(gè)操作數(shù)分別填入兩個(gè)文本框后,通過選擇組合框中的算法觸發(fā)運(yùn)算,如下:

        組合框的應(yīng)用

        from tkinter.ttk import *
        
        def calc(event):
               a = float(t1.get())
               b = float(t2.get())
               dic = {0:a+b,1:a-b,2:a*b,3:a/b}
               c = dic[comb.current()]
               lbl.config(text=str(c))
        
        root = Tk()
        root.title('四則運(yùn)算')
        root.geometry('320x240')
        
        t1 = Entry(root)
        t1.place(relx=0.1,rely=0.1,relwidth=0.2,relheight=0.1)
        
        t2 = Entry(root)
        t2.place(relx=0.5,rely=0.1,relwidth=0.2,relheight=0.1)
        
        var = StringVar()
        
        comb = Combobox(root,textvariable=var,values=['加','減','乘','除',])
        comb.place(relx=0.1,rely=0.5,relwidth=0.2)
        comb.bind('<<ComboboxSelected>>',calc)
        
        lbl=Label(root,text='結(jié)果')
        lbl.place(relx=0.5,rely=0.7,relwidth=0.2,relheight=0.3)
        
        root.mainloop()
        
    • 3.6、滑塊:(Scale) 是一種 直觀地進(jìn)行數(shù)值輸入的交互控件,其主要屬性見下表:

      屬性 功能描述
      from_ 起始值(最小可取值)
      lable 標(biāo)簽文字,默認(rèn)為無(wú)
      length 滑塊控件實(shí)例寬(水平方向)或 高(垂直方向),默認(rèn)為100像素
      orient 滑塊控件實(shí)例呈現(xiàn)方向,VERTCAL或HORIZONTAL(默認(rèn))
      repeatdelay 鼠標(biāo)響應(yīng)延時(shí),默認(rèn)為 300ms
      resolution 分辨精度,即最小值間隔
      sliderlength 滑塊寬度,默認(rèn)為30 像素
      state 狀態(tài),若設(shè)置 state=DISABLED,則滑塊控件實(shí)例不可用
      tickinterval 標(biāo)尺間隔,默認(rèn)為0,若設(shè)置過小,則會(huì)重疊
      to 終止值(最大可取值)
      variable 返回?cái)?shù)值類型,可為IntVar(整數(shù))、DoubleVar(浮點(diǎn)數(shù))、或 StringVar(字符串)
      width 控件實(shí)例本身的寬度,默認(rèn)為15像素

      滑塊控件實(shí)例的主要方法比較簡(jiǎn)單,有 get()和set(值),分別為取值和將滑塊設(shè)在某特定值上?;瑝K實(shí)例也可綁定鼠標(biāo)左鍵釋放事件<ButtoonRelease-1>,并在執(zhí)行函數(shù)中添加參數(shù)event來(lái)實(shí)現(xiàn)事件響應(yīng)。
      例如:在一個(gè)窗體上設(shè)計(jì)一個(gè)200像素寬的水平滑塊,取值范圍為1.0~5.0,分辨精度為0.05,刻度間隔為 1,用鼠標(biāo)拖動(dòng)滑塊后釋放鼠標(biāo)可讀取滑塊值并顯示在標(biāo)簽上。效果如下:


      滑塊控件的應(yīng)用
      from tkinter  import  *
      
      def show(event):
            s = '滑塊的取值為' + str(var.get())
            lb.config(text=s)
      
      root = Tk()
      root.title('滑塊實(shí)驗(yàn)')
      root.geometry('320x180')
      var=DoubleVar()
      scl = Scale(root,orient=HORIZONTAL,length=200,from_=1.0,to=5.0,label='請(qǐng)拖動(dòng)滑塊',tickinterval=1,resolution=0.05,variable=var)
      scl.bind('<ButtonRelease-1>',show)
      scl.pack()
      
      lb = Label(root,text='')
      lb.pack()
      
      root.mainloop()
      
    • 3.7、菜單:(Menu)用于可視化地為一系列的命令分組,從而方便用戶找到和觸發(fā)執(zhí)行這些命令。這里Menu所實(shí)例化別的主要是菜單,其通式為:

      菜單實(shí)例名=Menu(根窗體)
      菜單分組1=Menu(菜單實(shí)例名)
      菜單實(shí)例名.add_cascade(<label=菜單分組1 顯示文本>,<menu=菜單分組1>)
      菜單分組1.add_command(<label=命令1文本>,<command=命令1函數(shù)名>)
      

      其中較為常見的方法有:add_cascade()、add_command()和add_separator(),分別用于添加一個(gè)菜單分組、添加一條菜單命令和添加一條分割線。
      利用Menu控件也可以創(chuàng)建快捷菜單(又稱為上下文菜單)。通常需要右擊彈出的控件實(shí)例綁定鼠標(biāo)右擊響應(yīng)事件<Button-3>,并指向一個(gè)捕獲event參數(shù)的自定義函數(shù),在該自定義函數(shù)中,將鼠標(biāo)的觸發(fā)位置event.x_root 和 event.y_root以post()方法傳給菜單。
      例子:仿照window自帶的“記事本”中的文件和編輯 菜單,實(shí)現(xiàn)在主菜單個(gè)快捷菜單上觸發(fā)菜單命令,并相應(yīng)改變窗體上的標(biāo)簽的文本內(nèi)容。效果如下:

      菜單和快捷菜單

      from tkinter import *
      
      def new():
           s = '新建'
           lb1.config(text=s)
      
      def ope():
           s = '打開'
           lb1.config(text=s)
      
      def sav():
           s = '保存'
           lb1.config(text=s)
      
      def cut():
           s = '剪切'
           lb1.config(text=s)
      
      def cop():
           s = '復(fù)制'
           lb1.config(text=s)
      
      def pas():
           s = '粘貼'
           lb1.config(text=s)
      
      def popupmenu(event):
           mainmenu.post(event.x_root,event.y_root)
      
      root = Tk()
      root.title('菜單實(shí)驗(yàn)')
      root.geometry('320x240')
      
      lb1 = Label(root,text='顯示信息',font=('黑體',32,'bold'))
      lb1.place(relx=0.2,rely=0.2)
      
      mainmenu = Menu(root)
      menuFile = Menu(mainmenu)  # 菜單分組 menuFile
      mainmenu.add_cascade(label="文件",menu=menuFile)
      menuFile.add_command(label="新建",command=new)
      menuFile.add_command(label="打開",command=ope)
      menuFile.add_command(label="保存",command=sav)
      menuFile.add_separator()  # 分割線
      menuFile.add_command(label="退出",command=root.destroy)
      
      menuEdit = Menu(mainmenu)  # 菜單分組 menuEdit
      mainmenu.add_cascade(label="編輯",menu=menuEdit)
      menuEdit.add_command(label="剪切",command=cut)
      menuEdit.add_command(label="復(fù)制",command=cop())
      menuEdit.add_command(label="粘貼",command=pas())
      
      root.config(menu=mainmenu)
      root.bind('Button-3',popupmenu) # 根窗體綁定鼠標(biāo)右擊響應(yīng)事件
      root.mainloop()
      
    • 3.8、子窗體:用Toplevel可新建一個(gè)顯示在最前面的子窗體,其通式為: 字體實(shí)例名=Toplevel(根窗體),子窗體與根窗體類似,也可設(shè)置title、geomerty等屬性,并在畫布上布局其他控件。如下的例子:在根窗體上創(chuàng)建菜單,觸發(fā)創(chuàng)建一個(gè)新的窗體

      根窗體與子窗體

      from tkinter import *
      
      def newwind():
            winNew = Toplevel(root)
            winNew.geometry('320x240')
            winNew.title('新窗體')
            lb2 = Label(winNew,text='我在新窗體上')
            lb2.place(relx=0.2,rely=0.2)
            btClose=Button(winNew,text='關(guān)閉',command=winNew.destroy)
            btClose.place(relx=0.7,rely=0.5)
      
      root = Tk()
      root.title('新建窗體實(shí)驗(yàn)')
      root.geometry('320x240')
      
      lb1 = Label(root,text='主窗體',font=('黑體',32,'bold'))
      lb1.place(relx=0.2,rely=0.2)
      
      mainmenu = Menu(root)
      menuFile = Menu(mainmenu)
      mainmenu.add_cascade(label='菜單',menu=menuFile)
      menuFile.add_command(label='新窗體',command=newwind)
      menuFile.add_separator()
      menuFile.add_command(label='退出',command=root.destroy)
      
      root.config(menu=mainmenu)
      root.mainloop()
      

      關(guān)閉窗體程序運(yùn)行的方法通常用 destory(),而不建議用 quit()。用Toplevel 所創(chuàng)建的子窗體是非模式(Modeless)的窗體,雖然初建時(shí)子窗體在最前面,但根窗體上的控件實(shí)例也是可以被操作的。

    • 3.9、模式對(duì)話框(Modal):是相對(duì)于前面介紹的非模式窗體而言的,所彈出的對(duì)話框必須應(yīng)答,在關(guān)閉之前無(wú)法操作其后面的其他窗體。常見的模式對(duì)話框有消息對(duì)話框、輸入對(duì)話框、文件選擇對(duì)話框、顏色選擇對(duì)話框等。

      • 3.9.1、交互對(duì)話框

        (一)、消息對(duì)話框: 引用 tkinter.messagebox 包,可使用消息對(duì)話框函數(shù)。執(zhí)行這些函數(shù),可彈出模式消息對(duì)話框,并根據(jù)用戶的響應(yīng)但會(huì)一個(gè)布爾值。其通式為:

         消息對(duì)話框函數(shù)(<title=標(biāo)題文本>,<message=消息文本>,[其他參數(shù)])
        

        看下面的例子:?jiǎn)螕舭粹o,彈出確認(rèn)取消對(duì)話框,并將用戶回答顯示在標(biāo)簽中。效果如下:


        確定取消對(duì)話框
        from tkinter import *
        import tkinter.messagebox
        
        def xz():
            answer=tkinter.messagebox.askokcancel('請(qǐng)選擇','請(qǐng)選擇確定或取消')
            if answer:
                lb.config(text='已確認(rèn)')
            else:
                lb.config(text='已取消')
        
        root = Tk()
        
        lb = Label(root,text='')
        lb.pack()
        btn=Button(root,text='彈出對(duì)話框',command=xz)
        btn.pack()
        root.mainloop()
        

        (二)、輸入對(duì)話框: 引用tkinter.simpledialog包,可彈出輸入對(duì)話框,用以接收用戶的簡(jiǎn)單輸入。輸入對(duì)話框常用 askstring()、askfloat()和askfloat() 三種函數(shù),分別用于接收字符串、整數(shù)和浮點(diǎn)數(shù)類型的輸入。
        如下面的例子:單擊按鈕,彈出輸入對(duì)話框,接收文本輸入顯示在窗體的標(biāo)簽上。如下:

        輸入對(duì)話框

        from tkinter.simpledialog import *
        
        def xz():
            s=askstring('請(qǐng)輸入','請(qǐng)輸入一串文字')
            lb.config(text=s)
        
        root = Tk()
        
        lb = Label(root,text='')
        lb.pack()
        btn=Button(root,text='彈出輸入對(duì)話框',command=xz)
        btn.pack()
        root.mainloop()
        
      • 3.9.2、文件選擇對(duì)話框:引用tkinter.filedialog包,可彈出文件選擇對(duì)話框,讓用戶直觀地選擇一個(gè)或一組文件,以供進(jìn)一步的文件操作。常用的文件選擇對(duì)話框函數(shù)有 askopenfilename()、askopenfilenames()和asksaveasfilename(),分別用于進(jìn)一步打開一個(gè)文件、一組文件和保存文件。其中,askopenfilename()和asksaveasfilenamme()函數(shù)的返回值類型為包含文件路徑的文件名字符串,而askopenfilenames()函數(shù)的返回值類型為元組。
        例如:?jiǎn)螕舭粹o,彈出文件選擇對(duì)話框(“打開”對(duì)話框),并將用戶所選擇的文件路徑和文件名顯示在窗體的標(biāo)簽上。如下

        文件選擇對(duì)話框

        from tkinter import *
        import tkinter.filedialog
        
        def xz():
            filename=tkinter.filedialog.askopenfilename()
            if filename != '':
                 lb.config(text='您選擇的文件是'+filename)
            else:
                 lb.config(text='您沒有選擇任何文件')
        
        root = Tk()
        
        lb = Label(root,text='')
        lb.pack()
        btn=Button(root,text='彈出文件選擇對(duì)話框',command=xz)
        btn.pack()
        root.mainloop()
        
      • 3.9.3、顏色選擇對(duì)話框:引用tkinter.colorchooser包,可使用 askcolor()函數(shù)彈出模式顏色選擇對(duì)話框,讓用戶可以個(gè)性化地設(shè)置顏色屬性。該函數(shù)的返回形式為包含RGB十進(jìn)制浮點(diǎn)元組和RGB十六進(jìn)制字符串的元組類型,例如:“((135.527343.52734375,167.65234375,186.7265625)),'#87a7ba'”。通常,可將其轉(zhuǎn)換為字符串類型后,再截取以十六進(jìn)制數(shù)表示的RGB顏色字符串用于為屬性賦值。
        舉例:?jiǎn)螕舭粹o,彈出顏色選擇對(duì)話框,并將用戶所選擇的顏色設(shè)置為窗體上標(biāo)簽的背景顏色,如下:

        顏色選擇對(duì)話框

        from tkinter import *
        import tkinter.colorchooser
        
        def xz():
            color=tkinter.colorchooser.askcolor()
            colorstr=str(color)
            print('打印字符串%s 切掉后=%s' % (colorstr,colorstr[-9:-2]))
            lb.config(text=colorstr[-9:-2],background=colorstr[-9:-2])
        
        root = Tk()
        
        lb = Label(root,text='請(qǐng)關(guān)注顏色的變化')
        lb.pack()
        btn=Button(root,text='彈出顏色選擇對(duì)話框',command=xz)
        btn.pack()
        root.mainloop()
        
  • 4、事件響應(yīng)
    用tkinter 可將用戶事件與自定義函數(shù)綁定,用鍵盤或鼠標(biāo)的動(dòng)作事件來(lái)響應(yīng)觸發(fā)自定義函數(shù)的執(zhí)行。其通式為:

    控件實(shí)例.bind(<事件代碼>,<函數(shù)名>)
    

    其中,事件代碼通常以半角小于號(hào)“<”和大于號(hào)“>” 界定,包括事件和按鍵等 2~3個(gè)部分,它們之間用減號(hào)分隔,常見事件代碼見下表:

    事件 事件代碼 備注
    單擊鼠標(biāo)左鍵 <ButtonPress-1> 可簡(jiǎn)寫為<Button-1> 或 <1>
    單擊鼠標(biāo)中鍵 <ButtonPress-2> 可簡(jiǎn)寫為<Button-2> 或 <2>
    單擊鼠標(biāo)右鍵 <ButtonPress-3> 可簡(jiǎn)寫為<Button-3> 或 <3>
    釋放鼠標(biāo)左鍵 <ButtonRelease-1> ---
    釋放鼠標(biāo)中鍵 <ButtonRelease-2> ---
    釋放鼠標(biāo)右鍵 <ButtonRelease-3> ---
    按住鼠標(biāo)左鍵移動(dòng) <B1-Motion> ---
    按住鼠標(biāo)中鍵移動(dòng) <B2-Motion> ---
    按住鼠標(biāo)右鍵移動(dòng) <B3-Motion> ---
    轉(zhuǎn)動(dòng)鼠標(biāo)滾輪 <MouseWheel> ---
    雙擊鼠標(biāo)左鍵 <Double-Button-1> ---
    鼠標(biāo)進(jìn)入控件實(shí)例 <Enter> 注意與回車事件的區(qū)別
    鼠標(biāo)離開控件實(shí)例 <Leave> ---
    鍵盤任意鍵 <Key> ---
    字母和數(shù)字 < Key-字母>,例如<key-a>、<Key-A> 簡(jiǎn)寫不帶小于和大于號(hào),例如:a,A和1等
    回車 <Return> <Tab>,<Shift>,<Control>(注意不能用<Ctrl>),<Alt>等類同
    空格 <Space> ---
    方向鍵 <Up> ,<Down>,<Left>,<Right> ---
    功能鍵 <Fn>例如:<F1>等 ---
    組合鍵 鍵名之間以減號(hào)鏈接,例如<Control-k>,<Shift-6>,<Alt-Up>等 注意大小寫

    例如,將框架控件實(shí)例frame 綁定鼠標(biāo)右鍵單擊事件,調(diào)用自定義函數(shù) myfunc()可表示為"frame.bind('<Button-3>',myfunc)",注意: myfunc后面沒有括號(hào)。將控件實(shí)例綁定到鍵盤事件和部分光標(biāo)不落在具體控件實(shí)例上的鼠標(biāo)事件時(shí),還需要設(shè)置該實(shí)例執(zhí)行focus_set() 方法獲得焦點(diǎn),才能對(duì)事件持續(xù)響應(yīng)。例如: frame.focus_set()。所調(diào)用的自定義函數(shù)若需要利用鼠標(biāo)或鍵盤的響應(yīng)值,可將event作為參數(shù),通過event的屬性獲取。event的屬性見下表:

    event屬性 意義
    x或y(注意是小寫) 相對(duì)于事件綁定控件實(shí)例左上角的坐標(biāo)值(像素)
    root_x或root_y(注意是小寫) 相對(duì)于顯示屏幕左上角的坐標(biāo)值(像素)
    char 可顯示的字符,若按鍵不可顯示,則返回為空字符串
    keysysm 字符或字符型按鍵名,如:“a”或“Escape”
    keysysm_num 按鍵的十進(jìn)制 ASCII 碼值

    例如:將標(biāo)簽綁定鍵盤任意鍵觸發(fā)事件并獲取焦點(diǎn),并將按鍵字符顯示在標(biāo)簽上


    響應(yīng)鍵盤事件
    from tkinter import *
    
    def show(event):
    s=event.keysym
    lb.config(text=s)
    
    root=Tk()
    root.title('按鍵實(shí)驗(yàn)')
    root.geometry('200x200')
    lb=Label(root,text='請(qǐng)按鍵',font=('黑體',48))
    lb.bind('<Key>',show)
    lb.focus_set()
    lb.pack()
    root.mainloop()
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,835評(píng)論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,676評(píng)論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,730評(píng)論 0 380
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,118評(píng)論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,873評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,266評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,330評(píng)論 3 443
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,482評(píng)論 0 289
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,036評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,846評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,025評(píng)論 1 371
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,575評(píng)論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,279評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,684評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,953評(píng)論 1 289
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,751評(píng)論 3 394
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,016評(píng)論 2 375

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