【问题标题】:How to select multiple checkboxes with SHIFT in tkinter?如何在 tkinter 中使用 SHIFT 选择多个复选框?
【发布时间】:2013-03-26 23:30:57
【问题描述】:

问题很简单,我在 Text 小部件中使用 window_create 创建了许多复选框。代码如下:

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()

这是它的样子:

我想选择多个复选框,如果我必须单击每个复选框,这很麻烦。那么有没有一种方法可以在这里使用SHIFT

【问题讨论】:

  • 您是否考虑过添加“全选”和“取消全选”按钮来做同样的事情,而不是绑定?大多数用户永远不会意识到他们可以通过 shift-click 来全选,而且您不能依赖他们阅读用户指南。
  • 是的,添加“全选”和“反向选择”按钮是我的计划。但有时使用“移位选择”会更好,例如您想选择几块复选框。
  • @BryanOakley 你能看一下选择的答案吗?如果将 for cb in self.chkbuttons[sl]: cb.toggle() 更改为 map(tk.Checkbutton.toggle, self.chkbuttons[self.start+1:end]) 它将不起作用,我不知道为什么。谢谢!

标签: python checkbox tkinter


【解决方案1】:

您应该将'<Shift-Button-1>' 事件绑定到每个检查按钮,并绑定'<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()

【讨论】:

  • 你确定这段代码有效吗?但它或多或少都有帮助,还是谢谢
  • @laike9m 是的,这段代码大部分是你的,我只添加了selectstartselectrange
  • 我通过简单地将map 替换为for 循环来使您的代码工作。我认为map 也应该工作,但它只是不工作。
  • @laike9m 我对代码进行了一些改进,这次我已经尝试过了。它应该可以正常工作。
  • 这肯定行得通。但我仍然不知道 map 函数有什么问题,毕竟使用 map 看起来很不错 b>
猜你喜欢
  • 2017-03-03
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 2015-11-30
  • 2014-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多