f.rodrigues
f.rodrigues

Reputation: 3587

Qt - Create Widget dynamically

I've this program I'm working on.

It's a simple drum looper that generates midi sound and play them. I'm still in the design part.

I placed all the widgets items, one by one by hand.

It was a tedious labor, which I think could be made a lot quicker by creating them dynamically.

How can I achieve this?

As you can see my code looks like a mess:

self.kick_1 = QtGui.QCheckBox(self)
self.kick_2 = QtGui.QCheckBox(self)
self.kick_3 = QtGui.QCheckBox(self)
self.kick_4 = QtGui.QCheckBox(self)
self.kick_5 = QtGui.QCheckBox(self)
self.kick_6 = QtGui.QCheckBox(self)
self.kick_7 = QtGui.QCheckBox(self)
self.kick_8 = QtGui.QCheckBox(self)
self.kick_9 = QtGui.QCheckBox(self)
self.kick_10 = QtGui.QCheckBox(self)
self.kick_11 = QtGui.QCheckBox(self)
self.kick_12 = QtGui.QCheckBox(self)
self.kick_13 = QtGui.QCheckBox(self)
self.kick_14 = QtGui.QCheckBox(self)
self.kick_15 = QtGui.QCheckBox(self)
self.kick_16 = QtGui.QCheckBox(self)
self.kick_1.setGeometry(QtCore.QRect(120, 60, 16, 17))
self.kick_2.setGeometry(QtCore.QRect(150, 60, 16, 17))
self.kick_3.setGeometry(QtCore.QRect(180, 60, 16, 17))
self.kick_7.setGeometry(QtCore.QRect(300, 60, 16, 17))
self.kick_4.setGeometry(QtCore.QRect(210, 60, 16, 17))
self.kick_5.setGeometry(QtCore.QRect(240, 60, 16, 17))
self.kick_6.setGeometry(QtCore.QRect(270, 60, 16, 17))
self.kick_14.setGeometry(QtCore.QRect(510, 60, 16, 17))
self.kick_11.setGeometry(QtCore.QRect(420, 60, 16, 17))
self.kick_8.setGeometry(QtCore.QRect(330, 60, 16, 17))
self.kick_9.setGeometry(QtCore.QRect(360, 60, 16, 17))
self.kick_12.setGeometry(QtCore.QRect(450, 60, 16, 17))
self.kick_13.setGeometry(QtCore.QRect(480, 60, 16, 17))
self.kick_10.setGeometry(QtCore.QRect(390, 60, 16, 17))
self.kick_15.setGeometry(QtCore.QRect(540, 60, 16, 17))
self.kick_16.setGeometry(QtCore.QRect(570, 60, 16, 17))

All of this just to create 16 check boxes and place them side by side(30 pixels apart)

Upvotes: 0

Views: 547

Answers (2)

sebastian
sebastian

Reputation: 9696

First off, you could use a list to keep all those widgets instead of those "manually" named variables:

self.kicks = [QtGui.QCheckBox(self) for _ in xrange(16)]

Second, you should take a serious look at layout managers. I haven't yet come across the need to use absolute positioning. E.g. an QHBoxLayout will arrange all added widgets adjacent in a horizontal row, pretty much what you're doing:

layout = QtGui.QHBoxLayout()
# add all the checkboxes
for kick in self.kicks:
    layout.addWidget(kick)
# tell your widget to actually use this layout
self.setLayout(layout)

Upvotes: 2

Steve Barnes
Steve Barnes

Reputation: 28415

If you need to continue with absolute positioning you could use loops:

start_at_x = 120
step = 30
y = 60
for n in range(1,17):
    cb = QtGui.QCheckBox(self)
    cb.setGeometry(QtCore.QRect(start_at_x+(step*n), y, 16, 17))
    setattr(self, 'kick_%n' % n, cb)

but you also should look at the layout options provided by QT as they provide much more flexibility.

Upvotes: 0

Related Questions