1
 self.a = QtGui.QRadioButton()
 self.b = QtGui.QRadioButton()

when i have an array: arr = ["a","b" ,"c"....."x","z"]

how do I create it more efficient instead of 26 times?

manChan
  • 73
  • 2
  • 9
  • possible duplicate: http://stackoverflow.com/questions/16060899/alphabet-range-python – cel Apr 04 '15 at 10:20

2 Answers2

1

Don't assign each radio button to its own instance variable in your class, use a dictionary instead:

import string
from QtGui import QRadioButton

class RadioButtons(object):    
    def __init__(self, keys=string.ascii_lowercase):
        self.buttons = {c: QRadioButton() for c in keys}

This will create a dictionary (using a dictionary comprehension) named self.buttons as an instance variable within objects of class RadioButtons. You can access individual buttons using a dictionary lookup:

rb.buttons['z']
>>> rb = RadioButtons()
>>> rb.buttons['a']
<__main__.QRadioButton object at 0x7f576c3666d0>
>>> rb.buttons['z']
<__main__.QRadioButton object at 0x7f576c36a550>

A dictionary is the way to go, but if you really must have each button as an instance variable, then you could do something like this:

class RadioButtons(object):    
    def __init__(self, keys=string.ascii_lowercase):
        self.__dict__.update({c: QRadioButton() for c in keys})

>>> rb = RadioButtons()
>>> rb.a
<__main__.QRadioButton object at 0x7f576c3666d0>
>>> rb.z
<__main__.QRadioButton object at 0x7f576c36a550>
mhawke
  • 84,695
  • 9
  • 117
  • 138
1

Very often, you don't need to keep a local reference to your buttons. In this case, you can safely forget them as long as they have a parent widget that will take care of destroying them.

Using a QButtonGroup and its global signal buttonClicked will also help manage a set of buttons in a generic way. But you can also connect each button to a single slot using partial to transmit a user-defined data that will help you identify which button generated the callback.

import sys
import string
from PyQt5 import QtWidgets, QtCore

class Window(QtWidgets.QDialog):
    def __init__(self):
        super().__init__()
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.letters = list(string.ascii_lowercase)

        self.lay = QtWidgets.QVBoxLayout(self)
        self.group = QtWidgets.QButtonGroup()

        # Create all the buttons
        for letter in self.letters:
            btn = QtWidgets.QRadioButton(letter, self)
            # In case you want to find it back later using findChild
            btn.setObjectName("btn_"+letter)
            self.group.addButton(btn)
            self.lay.addWidget(btn)

        self.group.buttonClicked.connect(self.btnCliked)

    def btnCliked(self, btn):
        # Do something with the button
        print(btn.text())

def main():
    qApp = QtWidgets.QApplication(sys.argv)
    win = Window()
    win.show()
    sys.exit(qApp.exec_())

if __name__ == '__main__':
    main()

Example with partial:

from functools import partial

[...]

for letter in self.letters:
    btn = QtWidgets.QRadioButton(letter, self)
    self.lay.addWidget(btn)
    btn.clicked.connect(partial(self.btnClicked, letter))

[...]

def btnCliked(self, letter):
    print(letter)
Cilyan
  • 7,883
  • 1
  • 29
  • 37
  • only one checkbox can be selected? I want to select more than one boxes...How can I write? thanks – manChan Apr 09 '15 at 08:32