无法创建2D默认无线电按钮

时间:2013-02-11 14:54:09

标签: python radio-button tkinter

我正在尝试使用默认值创建无线电按钮的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()

1 个答案:

答案 0 :(得分: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中创建一个滚动的框架,因此你的窗口最终会比你的屏幕高很多。