2020年8月28日 星期五

python tkinter 重要語法記錄

 

 

 

 

重要語法:

 

 

 

##=========================================================

Combobox的用法:

  

   

def printWarmOrMove(self):

    #if en_opt_WarmOrMove.get() == '警告':

    if self.get() == '警告':

        showinfo("Select", '只作警告')

    else:

        showinfo("Select", '將超過時間的信件移至目的信箱!')

 

 

def  mycombo(root,brow,myLabel,Entrywidth,opt_value):

 

#    Label_width=17

#    Label_Column=2

#    Entry_Column=3

   

    Label(root,text=myLabel,width=Label_width).grid(row=brow,column=Label_Column, sticky=E,columnspan=1)

 

    sv_opt_WarmOrMove = StringVar()                                                         è 建立 StringVar()

    en_opt_WarmOrMove = ttk.Combobox(root, width=Entrywidth, textvariable=sv_opt_WarmOrMove)  è 建主 combobox.

    en_opt_WarmOrMove['values'] = opt_value                                        è combobox item 加入 combobox[‘values’].

 

    en_opt_WarmOrMove.grid(row=brow,column=Entry_Column,sticky=W)      # 设置其在界面中出现的位置 column代表列 row 代表行

    en_opt_WarmOrMove.current(0)                                                          è 預設停在第一個item .

   

    #en_opt_WarmOrMove.bind("<<ComboboxSelected>>",printWarmOrMove) 

   

    en_opt_WarmOrMove.bind("<<ComboboxSelected>>",lambda e:printWarmOrMove(en_opt_WarmOrMove)) è 只傳入元件自己.

                                                                                                                  後來發現, 其實也可以 ,lambda e:printWarmOrMove(e) 再由 函數內自己解析 元件.

   

    return en_opt_WarmOrMove

 

 

##=========================================================

Listbox 如何用 for 取出所有item

 

    for item in listbox.get(0,END):

        mstart = item.index('>')+2

        mend   = item.index('.',mstart)

        #print(mstart,mend,item[mstart:mend])

        mtime = int(item[mstart:mend])

        if mtime > en_moveTimeInterval_value:

 

 

##==========================================================

如何建立網路磁碟機

 

def getmail(path,mailbox,driver):

    comNet = win32com.client.Dispatch("WScript.Network")

    NetDriver = driver                                                                                      è 本地端的磁碟機代號

    data = {}

    remote = path + '\\' + mailbox

    data['remote'] = remote

    data['local'] = NetDriver

    data['password'] = 'password'

    data['user'] = 'user'

    Lst_Folder = []

    

    #連線網路磁碟機

    #comNet.MapNetworkDrive(data['local'], data['remote'], False, data['user'], data['password']);

   

    try:

        comNet.MapNetworkDrive(data['local'], data['remote'], False, data['user'], data['password']);

    except:

        pass

        #print("win32net.NetUseAdd(None, 1, data) Fail")

 

 

          Lst_Folder_org = os.listdir(NetDriver)

 

##=========================================================

Listbox 沒有 scroll , 如要則要自己加, 同時要自己定位

##=========================================================

 

    brow = brow + 1

   

    scrolly=Scrollbar(root,width=20,orient=VERTICAL)                                    è 產生垂直的 scroll .

    scrolly.grid(row=brow,column=5,padx=(10,100),sticky=N+S+E)               è 定位, 注意, 要配合 padx(10,100), sticky 才能與listbox配好位罝.

   

    mailbody_listbox=Listbox(root,width=mailbody_width,height=mailbody_height,font=small_font)

    

    mailbody_listbox.grid(row=brow,column=2, sticky=W,padx=(30,0),columnspan=5)

      

    mailbody_listbox['yscrollcommand']=scrolly.set                                        è 告知 listbox yscrollcommand 要用 scroll.set

    scrolly['command'] = mailbody_listbox.yview                                                è 告知 scrolly command 要用 listbox.yview

 

 

##=========

如何在 bind 傳入 e 以及自訂義傳數. 注意這種作法會傳送機動的值, 而非傳送定義時的值.

##=========

## bind lambda ,記得要傳入 e è

就是傳入 event object , 提供給 mailbox_onselect(evt,myscreen) 接收.

 

box_mailbox1.bind('<<ListboxSelect>>', lambda e: mc.mailbox_onselect(e,myscreen))

 

 

## mailbox_onselect接收後, 透過 以下語法, 就可取出元件.

 

def mailbox_onselect(evt,myscreen):

    # Note here that Tkinter passes an event object to onselect()

    w = evt.widget                                 è 取出onselect的元件

    index = int(w.curselection()[0])                  è 取出 目前選取的是第幾個item

    value = w.get(index)                                      è 取出該item 內容. 應該為字串

    print('You selected item %d: "%s"' % (index, value))

   

    ## get file from value

    startpos = value.index('.')+1

    endpos   = value.index(' =>')

    email_filename = value[startpos:endpos]  è 取出 msg 的檔名.  è 等同於 substring(start,endpos)

 

          ## 如何取出元件名稱, w Listbox元件, 不是元件名稱, 取出元件名稱要用:

       if str(w) == '.!listbox':

 

 

##=============

 

路徑名合併重點:

 

file = r"\\123.123.123.123\e$\aa\bb\cc”+ "\\" +mailbox + "\\" + email_filename

 

重點1:

r” "\\123.123.123.123\e$\aa\bb\cc”

r會保留字串內的 \ , 但注意最後不可為 \” , 否則仍會出錯. 所以要去掉最後的 \.

“\\” 中間的 \ 要改用 \\,

 

 

##==============================================

Listbox內某個item 的設定, 要用 listbox.itemconfig(index,{設定,設定})

##==============================================

mailbody_listbox.insert(END, tt)   è 由後面END往後再加入, 所以表示也可以間加入. 如要刪除則 .delete(0,END)

mailbody_listbox.itemconfig(item_cnt, {'fg':color,'bg':'yellow'})

 

 

##===========

部份widget 沒有text , 是要用 以下指令指定內容, 例如Entry:

aa.delete(0,end)

aa.insert(0, def_text_val)

 

Label 如沒掛 StringVar, 可用

Label[‘text’]指定字串內容.

 

##==========

 

 

##===========

aa = Button(..).grid(…) 會失效, 要分開寫

 

aa = Button(..)

aa.grid(…) aa才會有效

 

##===========

 

aa = Button(….command=somefunc) ç 不會傳送 event 參數, 如要自代參數要用

 

aa = Button(….command=lambda: x:somefunc(x,para1,para2,para3) ç lambda 那個 x 就是 event object.

 

如要傳event 則要分開指定

Aa = Button()

aa.bind(‘<Button-1>’,somefunc)

mouse 的三個按鍵:

‘<Button-1>’

‘<Button-2>’

‘<Button-3>’

 

 

##======================================================================

tkinter 如要作定時循環作業, 無法用正常 thread進行定時作業, 而要用 root.after(秒數量1000, somefunc) 的方式重覆call 自己.

 

def reshowmailbox(…):

 

 

  if CheckVar1.get() == 1 :

        root.after(int(en_TimeInterval.get())*1000, lambda: reshowmailbox(….)

        print('reshowmailbox root after ')

 

##===========

由於 Checkbutton 沒有 get 可以取出值, 故要去存取他的 BooleanVar,

為方便存取 root 上的各元件, 故最好要自訂一個dict 去記錄screen 上有那些元作, 這樣才能將 screen 拆成不同部份單獨完成.

像我這個例子就是用myscreen[‘mailbox_listbox’] = mailbox_listbox

 

 

##========================

 

Checkbox 無法取得他是否己勾選, 要去檢查內含在它內部的 IntVar().

CheckVar1 = IntVar()

myscreen['CheckVar1'] = CheckVar1

 

CheckVar1.get() ç 這樣取出,

 

##==================================

##============================================

 

 

  comNet = win32com.client.Dispatch("WScript.Network")

    NetDriver = driver

    data = {}

    #remote = r'\\192.168.x.x\d$\aaa\bbbs\ccc.com\usermailfolder'

    remote = path + '\\' + mailbox

    data['remote'] = remote

    data['local'] = NetDriver

    data['password'] = 'password'

    data['user'] = 'user'

    Lst_Folder = []

    

    #連線網路磁碟機

    #comNet.MapNetworkDrive(data['local'], data['remote'], False, data['user'], data['password']);

    

    try:

        comNet.MapNetworkDrive(data['local'], data['remote'], False, data['user'], data['password']);

 

 

##==============================

listbox 的長度要用 size()

 

user_listbox=Listbox(root,…)

user_listbox.grid(row=brow..)

 

   for item in items:

        f_item = "{0:30}".format(item)

        user_listbox.insert(END, f_item)

 

 

    if user_listbox.size() > 1:

        user_listbox.itemconfig(0, {'fg':'red'})

 

##==============================

## 剛發現好用的 exec() 類似 clipper macro

   Clipper macro :

##==============================

     cMacro := "DTOC(DATE())"

     ? &cMacro

     ? &(INDEXKEY(0))

##==============================

 

 

for i in range(5):

    object = 'test' + str(i) + '=' + str(i*2)

    print(object)

    exec(object)   ## è 結果真的產生了 test1/test2… test5的變數.

 

##==============================