Python Tkinter 网格复选框

Jer*_*y G 4 python checkbox grid tkinter

我想知道是否有一种简单的方法可以使用 Tkinter 创建复选框网格。我正在尝试制作一个由 10 行和 10 列(即 100 个复选框)组成的网格,以便每行只能选择两个复选框。

编辑:我正在使用带有spyder的python 2.7

到目前为止我所拥有的:

from Tkinter import*

master = Tk()
master.title("Select Groups")

rows=10
columns=10


for x in range(rows):
    for y in range(columns):
        Label(master, text= "Group %s"%(y+1)).grid(row=0,column=y+1)
        Label(master, text= "Test %s"%(x+1)).grid(row=x+1,column=0)
        Checkbutton(master).grid(row=x+1, column=y+1)

mainloop()
Run Code Online (Sandbox Code Playgroud)

一旦选择了两个复选框,我就尝试使用 state='Disabled' 使一行变灰。

PM *_*ing 5

这是一个将所有内容放入类中的版本,因此我们不需要使用全局变量。它还避免了import *在 Python 中通常被认为是不好的风格的构造。确实,使用了很多示例代码import *,但这不是一个好的做法,因为它用导入模块中的所有名称弄乱了全局命名空间。因此,这些名称可能与您自己的变量的名称冲突,也可能与您使用 导入的其他模块的名称冲突import *

当窗口关闭时,程序会打印每个测试行的所选组的列表。

#!/usr/bin/env python

''' Create a grid of Tkinter Checkbuttons

    Each row permits a maximum of two selected buttons

    From http://stackoverflow.com/q/31410640/4014959

    Written by PM 2Ring 2015.07.15
'''

import Tkinter as tk

class CheckGrid(object):
    ''' A grid of Checkbuttons '''
    def __init__(self, rows=10, columns=10):
        master = tk.Tk()
        master.title("Select Groups")

        rowrange = range(rows)
        colrange = range(columns)

        #Create the grid labels
        for x in colrange:
            w = tk.Label(master, text="Group %s" % (x + 1))
            w.grid(row=0, column=x+1)

        for y in rowrange:
            w = tk.Label(master, text="Test %s" % (y + 1))
            w.grid(row=y+1, column=0)

        #Create the Checkbuttons & save them for future reference
        self.grid = []
        for y in rowrange:
            row = []
            for x in colrange:
                b = tk.Checkbutton(master)

                #Store the button's position and value as attributes
                b.pos = (y, x)
                b.var = tk.IntVar()

                #Create a callback bound to this button
                func = lambda w=b: self.check_cb(w)
                b.config(variable=b.var, command=func)
                b.grid(row=y+1, column=x+1)
                row.append(b)
            self.grid.append(row)

        #Track the number of on buttons in each row
        self.rowstate = rows * [0]

        master.mainloop()

    def check_cb(self, button):
        ''' Checkbutton callback '''
        state = button.var.get()
        y, x = button.pos

        #Get the row containing this button
        row = self.grid[y]

        if state == 1:
           self.rowstate[y] += 1 
           if self.rowstate[y] == 2:
               #Disable all currently off buttons in this row
               for b in row:
                   if b.var.get() == 0:
                        b.config(state=tk.DISABLED)
        else:
           self.rowstate[y] -= 1 
           if self.rowstate[y] == 1:
               #Enable all currently off buttons in this row
               for b in row:
                   if b.var.get() == 0:
                        b.config(state=tk.NORMAL)

        #print y, x, state, self.rowstate[y] 

    def get_checked(self):
        ''' Make a list of the selected Groups in each row'''
        data = []
        for row in self.grid:
            data.append([x + 1 for x, b in enumerate(row) if b.var.get()])
        return data


def main():
    g = CheckGrid(rows=10, columns=10)

    #Print selected Groups in each Test row when the window closes
    data = g.get_checked()
    for y, row in enumerate(data):
        print "Test %2d: %s" % (y + 1, row)


if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)