2016-03-15 46 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 :) –