我的示例使用QT,但在其他情境中肯定也很有用。
在下面的示例中,Export类的create函数在运行时创建一些函数,作为参数传递局部变量。当按下QT GUI上的按钮时,将调用这些函数:
try:
from PyQt4 import QtGui,QtCore
from PyQt4.QtGui import *
from PyQt4.QtCore import *
except : raise Exception("failed to import QT. Is it installed ?")
import time,copy
class Export(QTableWidget):
class Field:
def __init__(self,name):
self.name = name
def __init__(self):
self.fields = []
def add(self,name):
self.fields.append(self.Field(name))
def create(self,export_function):
QTableWidget.__init__(self,len(self.fields),3)
for index,field in enumerate(self.fields):
self.setItem(index,0,QTableWidgetItem(field.name))
editable_widget = QTableWidgetItem("0")
self.setItem(index,1,QTableWidgetItem(editable_widget))
print "creating export function: ",field.name,editable_widget
def export(field_name=field.name,widget=editable_widget):
print "export ",field_name,widget
value = widget.text()
export_function(field_name,value)
export_button = QtGui.QPushButton('set', self)
export_button.clicked.connect(export)
self.setCellWidget(index,2,export_button)
class Export_Qt(QMainWindow):
def __init__(self,parent=None):
QMainWindow.__init__(self, parent)
main_widget = QWidget(self)
layout = QVBoxLayout(main_widget)
export = Export()
export.add("A")
export.add("B")
def export_function(field,value): print field,":",value
export.create(export_function)
layout.addWidget(export)
main_widget.setLayout(layout)
self.setCentralWidget(main_widget)
self.resize(500,350)
if __name__ == '__main__' :
app = QApplication([])
main_window = Export_Qt(parent=None)
main_window.show()
try:
while True:
main_window.update()
QApplication.processEvents()
time.sleep(0.05)
except KeyboardInterrupt: pass
except Exception as e : print e
让我感到惊讶的是,事情的一半是有效的。将显示GUI,控制台将打印:
creating export function: A <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9e9e0>
creating export function: B <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9ec20>
然后,如果我按下对应于“B”的按钮,控制台将打印:
export False <PyQt4.QtGui.QTableWidgetItem object at 0x7fef87c9ec20>
False : 0
所以,打印“假”是我期待的“B”。但是请注意QTableWidgetItem的地址是正确的,所以这种方法似乎有意义。
快速修复的解决方案会很棒,但如果答案也提供了一些关于python如何工作的见解,我会非常高兴
注意:我知道只有一个名称属性的类字段没有意义。这是因为上面的代码简化了我正在使用的实际代码。为了便于阅读。
答案 0 :(得分:0)
这有效:
class Export(QTableWidget):
class Field:
def __init__(self,name):
self.name = name
def __init__(self):
self.fields = []
self.editable_widgets = []
def add(self,name):
self.fields.append(self.Field(name))
def _create(self,field_index,export_function):
self.setItem(field_index,0,QTableWidgetItem(self.fields[field_index].name))
editable_widget = QTableWidgetItem("pouet")
self.editable_widgets.append(editable_widget)
self.setItem(field_index,1,editable_widget)
print "creating export function: ",self.fields[field_index].name,editable_widget,editable_widget.text()
def export():
print "export ",field_index,self.fields[field_index].name,self.editable_widgets[field_index]
export_function(self.fields[field_index].name,self.editable_widgets[field_index].text())
export_button = QtGui.QPushButton('set', self)
export_button.clicked.connect(export)
self.setCellWidget(field_index,2,export_button)
def create(self,export_function):
QTableWidget.__init__(self,len(self.fields),3)
for index in range(len(self.fields)):
self._create(index,export_function)
这是有道理的。离开create函数后,字段不再是有效地址。所以field_name = field.name没有意义。 另一方面,小部件仍然存在(在QT的某个地方管理),因此事情适用于它。
在上面的解决方案中,我确保在指向创建后仍指向仍然存在的内容。