refers this question, to-convert-string-to-variable-name-in-python
I would like to collect user input, but the input field differs through 'method' change, so i would like to generate something based on:
search_method = { 'id' : ['id'],
'detail' : ['catagory', 'price', 'enroll date'],
'drawer' : ['name', 'sex', 'state']
'internal' : ['transaction date', 'msg id']
}
serves as dynamic input field
the expected result is that the key generates as radio button, and will generate ['label', 'line edit'] pairs to certain radio selection
here is the test of exec inside pyqt (clearLayout borrowed from user3369214
steps:
- create widgets
- create function that add them to layouts
- connect signal to function that change the layout
the advantage compared to add them one by one is that this is flexible to extend and convenient to collect data back,(most importantly, short), but program happens to say
NameError: global name 'self' is not defined
or SyntaxError: can't assign to function call
there might be some scope or internal problem, hope someone could help or some high-order function thing might help?
from PyQt4 import QtCore, QtGui
import sys
class TestDialog(QtGui.QDialog):
def __init__(self, parent = None):
super(TestDialog, self).__init__()
self.initUI()
def clearLayout(self, layout)
if layout != None:
while layout.count():
child = layout.takeAt(0)
if child.widget() is not None:
child.widget().deleteLater()
elif child.layout() is not None:
self.clearLayout(child.layout())
layout.setParent(None)
def initUI(self):
search_method = { 'id' : ['id'],
'detail' : ['catagory', 'price', 'enroll date'],
'drawer' : ['name', 'sex', 'state']
'internal' : ['transaction date', 'msg id']
}
self.layTop = QtGui.QHBoxLayout()
self.lblBy = QtGui.QLabel("By")
self.layTop.addWidget(self.lblBy)
for option in search_method.keys():
exec('self.rad_' + option + ' = QtGui.QRadioButton("' + option + '")')
exec('self.layTop.addWidget(self.rad_' + option + ')')
self.vlay = QtGui.QHBoxLayout()
self.vlay.addLayout(self.layTop)
self.layInput = QtGui.QVBoxLayout()
for option in search_method.keys():
code = 'def by_' + option + '():'
code += 'self.clearLayout(self.layInput)'
for input_field in search_method[option]:
code += 'self.lay_' + input_field + ' = QtGui.QHBoxLayout()'
code += ';self.lbl_' + input_field + ' = QtGui.QLabel("' + input_field + '")'
code += ';self.edit_' + input_field + ' = QtGui.QLineEdit()'
code += ';self.lay_' + input_field + '.addWidget(self.lbl_' + input_field + ')'
code += ';self.lay_' + input_field + '.addWidget(self.edit_' + input_field + ')'
code += ';self.layInput.addLayout(self.lay_' + input_field + ')'
exec code
for option in options.keys():
exec('self.rad_' + option + '.toggled.connect(by_' + option + ')')
self.setLayout(self.vlay)
app = QtGui.QApplication(sys.argv)
testDialog = TestDialog()
testDialog.show()
sys.exit(testDialog.exec_())
I've also test in normal class, but that works fine ( could recognize the 'self')
class A:
def __init__(self, parm1, parm2):
self.parm1 = parm1
self.parm2 = parm2
def display(self):
to_exec = ''
to_exec += 'def jack():'
to_exec += 'print "hey hey hey"'
exec(to_exec)
exec('print self.parm' + '1')
exec('print self.parm' + '2')
exec('jack()')
def aha(self):
exec(self.display()')
a = A('hello', 'world')
exec 'a.aha()'