PyQt: 程序化创建QT控件
有时候,我们需要根据列表中的值来创建很多小部件(比如 QtGui.QLineEdit())。但是我们并不知道这个列表里到底有多少个值。为了处理这个问题,我可以写一个循环,让它根据列表里的值来运行多次……比如:
for each in myList:
myLineEdit = QtGui.QLineEdit("myLineEdit")
不过,这种方法有个问题,就是每次循环都会用同一个变量名,这样之后就没办法再访问到 myLineEdit 这个变量了。我听说有些人用 eval() 或 exec() 函数成功解决了这个问题。如果有其他方法也可以做到,请分享一下。下面是一个可以开始的示例代码(如果你想的话):
from PyQt4 import QtCore, QtGui
app = QtGui.QApplication(sys.argv)
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
mainQWidget = QtGui.QWidget()
mainLayout=QtGui.QVBoxLayout()
for i in range(5):
exec( 'myGroupBox'+str(i)+'= QtGui.QGroupBox() ' )
exec( 'myLayout'+str(i)+' = QtGui.QHBoxLayout()' )
exec( 'label'+str(i)+'=QtGui.QLabel("Name '+str(i)+': ")' )
exec( 'self.myLineEdit'+str(i)+'=QtGui.QLineEdit()' )
exec( 'myLayout'+str(i)+'.addWidget(label'+str(i)+')' )
exec( 'myLayout'+str(i)+'.addWidget(self.myLineEdit'+str(i)+', QtCore.Qt.AlignRight)' )
exec( 'myGroupBox'+str(i)+'.setLayout(myLayout'+str(i)+')' )
exec( 'mainLayout.addWidget(myGroupBox'+str(i)+')' )
mainQWidget.setLayout(mainLayout)
self.setCentralWidget(mainQWidget)
window = MainWindow()
window.show()
window.resize(480,320)
sys.exit(app.exec_())
另一个示例:
from PyQt4 import QtCore, QtGui
import random
app = QtGui.QApplication(sys.argv)
class MainWindow(QtGui.QMainWindow):
def __init__(self, argList):
super(MainWindow, self).__init__()
self.argList=argList
mainQWidget = QtGui.QWidget()
mainLayout=QtGui.QVBoxLayout()
for i in range(len(self.argList)):
exec( 'myGroupBox'+str(i)+'= QtGui.QGroupBox() ' )
exec( 'myLayout'+str(i)+' = QtGui.QHBoxLayout()' )
exec( 'label'+str(i)+'=QtGui.QLabel("Name '+str(self.argList[i])+': ")' )
exec( 'label'+str(i)+'.setFixedWidth(100)' )
exec( 'self.myLineEdit'+str(i)+'=QtGui.QLineEdit()' )
exec( 'self.myLineEdit'+str(i)+'.setText("'+str(random.random())+'")' )
exec( 'myLayout'+str(i)+'.addWidget(label'+str(i)+')' )
exec( 'myLayout'+str(i)+'.addWidget(self.myLineEdit'+str(i)+', QtCore.Qt.AlignRight)' )
exec( 'myGroupBox'+str(i)+'.setLayout(myLayout'+str(i)+')' )
exec( 'mainLayout.addWidget(myGroupBox'+str(i)+')' )
ButtonBox = QtGui.QGroupBox()
ButtonsLayout = QtGui.QHBoxLayout()
Button_01 = QtGui.QPushButton("Close")
Button_01.clicked.connect(self.close)
Button_02 = QtGui.QPushButton("Print")
Button_02.clicked.connect(self.printOut)
ButtonsLayout.addWidget(Button_01)
ButtonsLayout.addWidget(Button_02)
ButtonBox.setLayout(ButtonsLayout)
mainLayout.addWidget(ButtonBox)
mainQWidget.setLayout(mainLayout)
self.setCentralWidget(mainQWidget)
def printOut(self):
for i in range(len(self.argList)):
exec( 'print self.myLineEdit'+str(i)+'.text()' )
def close(self):
sys.exit()
myList=['One','Two','Tree','Four','Five','Six','Seven']
window = MainWindow(myList)
window.show()
window.resize(480,320)
sys.exit(app.exec_())
1 个回答
9
处理这种情况的一个简单方法是使用一个列表:
lineEdits = []
for _ in range(5):
myLineEdit = QtGui.QLineEdit("myLineEdit")
lineEdits.append(myLineEdit)
myLayout = QtGui.QHBoxLayout()
for lineEdit in lineEdits:
myLayout.addWidget(lineEdit)
另外,如果你想以后通过一个键来查找某个小部件,可以使用字典:
lineEdits = {}
for i in range(5):
myLineEdit = QtGui.QLineEdit("myLineEdit")
lineEdits[i] = myLineEdit
lineEdits[3].setText("My new text")