Search code examples
pythonpyqtpyqt4qcheckbox

Call objects from a list which reproduces object names


I'm creating an application which has many checkBoxes. Every 4 checkBoxes are inside of a groupBox_n (n=36) and these groupBoxes are then inside of another groupBox.

Each checkBox is named following a certain rule which is very convenient for me. I want to have access to each of them, but I don't want to type their name every time. So I though about reproducing their names in a list, so that I could iterate over the list and have control, depending on their names.

But when I try to connect a button calling a string from my list, I'm not able to do that. Here I reproduced an example with a QLineEdit.

Is it possible to do something like that?

Calling findChildrendoes not help me, because then I don't know what is the position of my checkBox in my application, or "who is who" there. Calling by ObjectName is also not possible, is it?

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(400, 300)
        self.gridLayout = QtGui.QGridLayout(Form)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))

        self.My_lineEdit = QtGui.QLineEdit(Form)
        self.My_lineEdit.setObjectName(_fromUtf8("My_lineEdit"))

        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
        self.pushButton = QtGui.QPushButton(Form)
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)

        MyStrinng = 'My_lineEdit'
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.Mystring.clear)

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

Like this, PyQt does not recognize my string as the object's name. I also tried to make a PyQt string with QCore.QString('My_lineEdit'), but QString is not available for my version (you can see here)

with this I can reproduce the names of all my checkboxes.

names = []

for x in range(0, 6):
    for y in range(0, 6):
        for z in range(1, 5):
            Names = 's'+str(x)+str(y)+'0'+str(z)
            names.append(Names)
print(names)

Solution

  • If you want to find an object by its object, the simplest option is to use findChild():

    T QObject::findChild(const QString &name = QString(), Qt::FindChildOptions options = Qt::FindChildrenRecursively) const

    Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object. Omitting the name argument causes all object names to be matched. The search is performed recursively, unless options specifies the option FindDirectChildrenOnly.

    If there is more than one child matching the search, the most direct ancestor is returned. If there are several direct ancestors, it is undefined which one will be returned. In that case, findChildren() should be used.

    This example returns a child QPushButton of parentWidget named "button1", even if the button isn't a direct child of the parent:

    QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
    

    The example in C++ that is in the documentation would be translated to python of the following form:

    button = parentWidget.findChild(QPushButton, "button1")
    

    In your case:

    class Ui_Form(object):
        def setupUi(self, Form):
            ...
            # change self.lineEdit to self.My_lineEdit
            #Form is the parent of My_lineEdit                     
            self.My_lineEdit = QtGui.QLineEdit(Form) 
            self.My_lineEdit.setObjectName(_fromUtf8("My_lineEdit"))
    
            self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
    
            ...
    
            le = Form.findChild(QtGui.QLineEdit, "My_lineEdit")
            self.pushButton.clicked.connect(le.clear)