2013-03-26 107 views
1

這個問題很簡單,我創建了一個使用window_create。這裏一個文本小很多複選框是代碼:如何在tkinter中用SHIFT選擇多個複選框?

import tkinter as tk 

root = tk.Tk() 
sb = tk.Scrollbar(orient="vertical") 
text = tk.Text(root, width=40, height=20, yscrollcommand=sb.set) 
sb.config(command=text.yview) 
sb.pack(side="right",fill="y") 
text.pack(side="top",fill="both",expand=True) 
for i in range(30): 
    cb = tk.Checkbutton(text="checkbutton %s" % i,padx=0,pady=0,bd=0) 
    text.window_create("end", window=cb) 
    text.insert("end", "\n") 

root.mainloop() 

,這裏是什麼樣子:

enter image description here

我想選擇多個複選框,如果我必須單擊每個複選框,這很麻煩。那麼有沒有辦法可以在這裏使用SHIFT

+2

取而代之的綁定,您曾經考慮加入「全選」和「取消選擇所有」按鈕做同樣的事情?大多數用戶永遠不會意識到他們可以通過點擊來選擇全部,而且您不能依賴他們閱讀用戶指南。 – 2013-03-26 10:50:43

+0

是的,我的計劃中添加了「全選」和「反選」按鈕。但有時使用「shift-select」會更好,例如您想選擇幾個複選框。 – laike9m 2013-03-26 12:37:26

+0

@BryanOakley你可以看看所選的答案嗎?如果在'self.chkbuttons [sl]中更改cb: cb.toggle()'到'map(tk.Checkbutton.toggle,self.chkbuttons [self.start + 1:end])'它將不起作用,我不知道爲什麼.Thx! – laike9m 2013-03-27 01:41:14

回答

2

您應該將'<Shift-Button-1>'事件綁定到每個checkbutton以及'<Button-1>以指示應該選擇的範圍的開始。另外,還要考慮到包裝你的代碼的類更好的可讀性:

class App: 
    def __init__(self, root): 
     self.start = 0 
     self.root = root 
     self.sb = tk.Scrollbar(orient="vertical") 
     text = tk.Text(root, width=40, height=20, yscrollcommand=self.sb.set) 
     self.sb.config(command=text.yview) 
     self.sb.pack(side="right",fill="y") 
     text.pack(side="top", fill="both", expand=True) 
     self.chkbuttons = [tk.Checkbutton(text="checkbutton %s" % i,padx=0,pady=0,bd=0) 
          for i in range(30)]       
     for cb in self.chkbuttons: 
      text.window_create("end", window=cb) 
      text.insert("end", "\n") 
      cb.bind("<Button-1>", self.selectstart) 
      cb.bind("<Shift-Button-1>", self.selectrange) 

    def selectstart(self, event): 
     self.start = self.chkbuttons.index(event.widget) 

    def selectrange(self, event): 
     start = self.start 
     end = self.chkbuttons.index(event.widget) 
     sl = slice(min(start, end)+1, max(start, end)) 
     for cb in self.chkbuttons[sl]: 
      cb.toggle() 
     self.start = end 

if __name__ == '__main__': 
    root = tk.Tk() 
    app = App(root) 
    root.mainloop() 
+0

您確定此代碼有效嗎?但它或多或少有所幫助,無論如何感謝 – laike9m 2013-03-26 13:15:15

+0

@ laike9m是的,大部分代碼都是您自己,我只添加了'selectstart'和'selectrange'。 – 2013-03-26 13:25:06

+0

我通過簡單地用for循環替換'map'來使你的代碼工作。我認爲'map'也應該可以工作,但它不會起作用。 – laike9m 2013-03-26 14:40:40