0

我正在尝试使用默认值创建一个 2D 单选按钮网格。网格可能有多达 256 行,但总是 3 列。我进行了很多研究并尝试了许多选项,这是我目前拥有的最好的代码。显然我是 Python 和 Tkinter 的新手,因此非常感谢任何其他解决我的困境(和代码编写)的建议。另外请记住,我需要回读每一行单选按钮以确定选中了哪一个。

import Tkinter as tk
from Tkinter import *

class GUI(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.pack()
        self.initUI()

    def initUI(self):
        # the 5Hz radio button should be selected as default
        self.freqs=['1Hz','5Hz','10Hz']
        self.numFreqs = len(self.freqs)
        #val and var are set up to try to establish the defaults
        #every 3 vals = 1 var therfore the middle val should = var
        # val 0,1,2 = var 1 , val 3,4,5 = var 4 , val 6,7,8 = var 7
        # this should allow the 5hx radiobuttonto be default selected
        self.val = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
        self.var=[1,4,7,10,13]
        self.var[0] = IntVar()
        self.var[1] = IntVar()
        self.var[2] = IntVar()
        self.var[3] = IntVar()
        self.var[4] = IntVar()
        self.cButtons = []
        self.rButtons1 = []
        self.rButtons2 = []
        self.rButtons3 = []

        self.textLbls = ['Choice 1', 'Choice 2', 'Choice 3','Choice 4','Choice 5']

        #build enough values for 256 rows of 3 radiobuttons
        #For var = [1,4,7,10...  val = [0,1,2,  3,4,5,  6,7,8... so vars match vals on the 5hz radiobutton
        #Can't do this since it creates the'many already selected bug'
        #See http://stackoverflow.com/questions/5071559/tkinter-radio-button-initialization-bug
        #for i in range(len(self.var)):
            #self.var[i] = IntVar()

        for i in range(len(self.textLbls)):
            temp = self.val[(self.numFreqs*i)+1]
            temp1 = self.var[i]
            self.cButtons.append(Checkbutton(self, text=self.textLbls[i], onvalue=1, offvalue=0))
            self.cButtons[i].grid(row=i, column=2, sticky = W)
            Label(self, text='         Frequency:').grid(row=i, column=6)
            #variable connects group of radios for slection/clear of group
            #if value = variable this is default
            self.rButtons1.append(Radiobutton(self,  text=self.freqs[0], variable=self.var[i], value=self.val[(self.numFreqs*i)+0]))
            self.rButtons1[i].grid(row=i, column=7, padx=5)
            self.rButtons2.append(Radiobutton(self,  text=self.freqs[1], variable=self.var[i], value=self.val[(self.numFreqs*i)+1]))
            self.rButtons2[i].grid(row=i, column=8, padx=5)
            self.rButtons3.append(Radiobutton(self,  text=self.freqs[2], variable=self.var[i], value=self.val[(self.numFreqs*i)+2]))
            self.rButtons3[i].grid(row=i, column=9, padx=5)

def main():
    root = Tk()
    app = GUI(root)
    root.mainloop()

if __name__ == '__main__':
    main()
4

1 回答 1

1

不完全确定您在此代码上寻求帮助的问题是什么,但我做了一些快速更改,应该使其功能更强大:

import tkinter as tk
from tkinter import *

class GUI(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.pack()
        self.initUI()

    def initUI(self):
        # the 5Hz radio button should be selected as default
        self.freqs=['1Hz','5Hz','10Hz']
        self.numFreqs = len(self.freqs)
        #val and var are set up to try to establish the defaults
        #every 3 vals = 1 var therfore the middle val should = var
        # val 0,1,2 = var 1 , val 3,4,5 = var 4 , val 6,7,8 = var 7
        # this should allow the 5hz radiobutton to be default selected
        self.val = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]
        #You only really need to hold on to a reference to the IntVars, not the
        # entire widgets.  Declaring each "var" individually is also unneccesary
        self.checkButtonVars = []
        self.radioButtonsVars = []

        self.textLbls = ['Choice 1', 'Choice 2', 'Choice 3','Choice 4','Choice 5']
        #(your comment block)

        valueIter = iter(self.val)  #This will let us read the values 3 by 3
        for i,lbl in enumerate(self.textLbls):      #enumerate is a nice way to avoid range(len(x))
            tempVals = [next(valueIter) for x in range(3)]  #get the next 3 values
            #make a variable for the new CheckBox (and append it to our list)
            self.checkButtonVars.append(IntVar(value=0))
            #make a variable for the new RadioButton group (and append it to our list)
            self.radioButtonsVars.append(IntVar(value=tempVals[1]))

            #Make the checkboxes, radiobuttons and label for the line.
            Checkbutton(self, text=lbl, variable=self.checkButtonVars[i]).grid(row=i, column=2, sticky = W)
            Label(self, text='         Frequency:').grid(row=i, column=6)
            Radiobutton(self,  text=self.freqs[0], variable=self.radioButtonsVars[i], value=tempVals[0]).grid(row=i, column=7, padx=5)
            Radiobutton(self,  text=self.freqs[1], variable=self.radioButtonsVars[i], value=tempVals[1]).grid(row=i, column=8, padx=5)
            Radiobutton(self,  text=self.freqs[2], variable=self.radioButtonsVars[i], value=tempVals[2]).grid(row=i, column=9, padx=5)

        #I added a button to retrieve the values, this is just as a demo.
        self.printButton = Button(self,text='Return values',command=self.printVals)
        self.printButton.grid(row=i+1,column=8)


    def getRadioVals(self,*args):
        #returns the values in the radio buttons as a list
        return [x.get() for x in self.radioButtonsVars]

    def getCheckVals(self,*args):
        #returns the values in the checkboxes as a list
        return [x.get() for x in self.checkButtonVars]

    def printVals(self,*args):
        print('Radio Buttons: %s' %(self.getRadioVals()))
        print('Check Buttons: %s' %(self.getCheckVals()))


def main():
    root = Tk()
    app = GUI(root)
    root.mainloop()

if __name__ == '__main__':
    main()

如果您可以更好地描述您遇到的具体问题,则可能会解决这些问题。

另外,请注意:尝试垂直显示 256 个单选按钮可能会给您带来一些问题。据我所知,没有办法在标准 tkinter 中创建滚动框架,因此您的窗口最终会比屏幕高得多。

于 2013-02-13T01:14:37.567 回答