2016-03-15 48 views
2

refers this question, to-convert-string-to-variable-name-in-python生成功能使用EXEC不承认自己

放置小部件的PyQt我想收集用户输入,但输入外地不同,通过“方法”的变化,所以我想基础上产生的东西:

search_method = { 'id' : ['id'], 
        'detail' : ['catagory', 'price', 'enroll date'], 
        'drawer' : ['name', 'sex', 'state'] 
        'internal' : ['transaction date', 'msg id'] 
       } 

用作动态输入字段

预期的结果是该密钥生成作为单选按钮,并且将生成[“标签”,“行编辑”]对某些无线电选择

这里是高管的内部PyQt的 测试(clearLayout从user3369214

步骤:

  1. 创建部件
  2. 创建添加功能,他们布局
  3. 连接信号功能改变布局

优势相比,添加逐一的是,这是灵活的扩展,方便收集数据回来,(最重要的是,短),但程序恰好说

NameError: global name 'self' is not defined 
or SyntaxError: can't assign to function call 

可能会有一些范围或内部的问题,希望有人能帮助 或者一些高阶函数的东西可能有帮助?

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_()) 

我也测试在普通类,但工作正常(可以承认 '自我')

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()' 
+1

你需要在全局和局部变量的字典中传递,以使'exec'在正确的命名空间进行操作。所以正确的用法是'exec('string to exec',globals(),locals())'。但是,您应该只使用下面答案中的字典选项。如果可能,应尽量避免“exec”。 –

+0

是的,concatec exec是粗鲁的,thx为你的善意建议:) –

回答

1

exec是没有必要的。它使代码难以阅读。如何使用字典来保存小部件?

import sys 

from PyQt4 import QtGui 


class TestDialog(QtGui.QDialog): 
    def __init__(self, parent=None): 
     super(TestDialog, self).__init__(parent) 
     self.initUI() 

    def clearLayout(self, layout): 
     if layout is None: 
      return 
     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) 
     self.radios = {} 
     self.layouts = {} 
     self.labels = {} 
     self.edits = {} 

     for option in search_method: 
      r = self.radios[option] = QtGui.QRadioButton(option) 
      self.layTop.addWidget(r) 

     self.vlay = QtGui.QHBoxLayout() 
     self.vlay.addLayout(self.layTop) 
     self.layInput = QtGui.QVBoxLayout() 

     def by_option(option): 
      self.clearLayout(self.layInput) 
      for input_field in search_method[option]: 
       lbl = self.labels[input_field] = QtGui.QLabel(input_field) 
       edit = self.edits[input_field] = QtGui.QLineEdit() 
       layout = self.layouts[input_field] = QtGui.QHBoxLayout() 
       layout.addWidget(lbl) 
       layout.addWidget(edit) 
       self.layInput.addLayout(layout) 
      self.vlay.addLayout(self.layInput) 

     for option in search_method: 
      self.radios[option].toggled.connect(
       lambda yesno, option=option: by_option(option) 
      ) 

     self.setLayout(self.vlay) 


app = QtGui.QApplication(sys.argv) 
testDialog = TestDialog() 
testDialog.show() 
sys.exit(testDialog.exec_()) 
+0

非常感谢,我也尝试过使用一些字典来保存小部件,但不知道如何安排和生成。你确实解决了我的问题,Thx :) –

相关问题