使用PySide,我试图将几个数据控件连接到我从光盘读取的文件中的数据。所以我创建了一个从QAbstractItemModel派生的数据模型。应该是微不足道的吧?但是我遇到的一个问题是连接QLineEdit和QTextEdit控件来显示和允许编辑模型中的数据。
从QT文档中的Simple Widget Mapper和Combo Widget Mapper等示例中,我相信我必须拥有一行数据模型,并使用QWidgetMapper将该行中的单元格连接到编辑控件。 / p>
这是一个非常简化的程序,可以显示问题。此示例中的数据模型返回三个字符串x1,x2和x3。字符串从例如通过调用Update来“First(1)”到“First(2)”,即单击“Next”按钮。这是为了模拟从文件或任何地方读取的新值。主窗口有几个QLineEdits和一个QTextEdit,映射器应链接到模型数据。但数据不会显示在编辑控件中。
为了检查模型,我添加了一个QTableView。数据显示在那里,并在单击“下一步”时更新,因此它不是数据模型。这是在那里和编辑控件之间的东西。但我看不到我在做什么,小部件映射器示例正在做什么。
我做错了什么?
顺便说一下,走另一条路也行不通。如果我将一个setData()方法添加到模型中,并发出dataChanged,则键入行编辑的更改将转到表中。但即使发生这种情况,该项目也会从行编辑中消失。单击“下一步”后,将停止为QLineEdit和QTextEdit工作 - 不再调用setData()。但是如果我在表视图中编辑,仍会调用setData。
以下是示例代码:
#!/usr/bin/python
import sys
from PySide.QtCore import ( Qt, QAbstractItemModel,QModelIndex
)
from PySide.QtGui import ( QApplication, QMainWindow, QPushButton, QWidget,
QTextEdit, QLineEdit, QFormLayout, QTableView,
QDataWidgetMapper,
)
##############################################################################
class TModel(QAbstractItemModel):
"""
This model will have 1 row of 3 items
There will be a slot that will change the items. If they are displayed
in widgets, I want to see them update.
"""
def __init__(self, parent=None):
super(TModel, self).__init__(parent)
self.counter = 0
self.x1 = ""
self.x2 = ""
self.x3 = ""
self.Update()
def columnCount(self, index=QModelIndex()):
return 3
def rowCount(self, index=QModelIndex()):
return 1
def index(self, row, column, index=QModelIndex()):
if not self.hasIndex(row, column, index):
return QModelIndex()
return self.createIndex(row, column)
def parent(self, index):
return QModelIndex()
def hasChildren(self, index):
return False
def data(self, index, role=Qt.DisplayRole):
if index.isValid():
if role == Qt.DisplayRole:
if index.column() == 0:
return self.x1
elif index.column() == 1:
return self.x2
elif index.column() == 2:
return self.x3
return None
def headerData(self, section, orientation, role):
if role != Qt.DisplayRole:
return None
if orientation == Qt.Horizontal:
if section == 0:
return "col 1"
elif section == 1:
return "col 2"
elif section == 2:
return "col 3"
def Update(self):
self.beginResetModel()
self.x1 = "First (%d)"%self.counter
self.x2 = "Second (%d)"%self.counter
self.x3 = "Third (%d)"%self.counter
self.counter += 1
self.endResetModel()
##############################################################################
class TMainWindow(QMainWindow):
"""Main GUI object"""
def __init__(self, parent=None):
super(TMainWindow, self).__init__(parent)
self.DataModel = TModel()
self.Mapper = QDataWidgetMapper()
self.Mapper.setSubmitPolicy(self.Mapper.AutoSubmit)
self.Mapper.setModel(self.DataModel)
self.FirstFieldEdit = QLineEdit()
self.SecondFieldEdit = QLineEdit()
self.ThirdFieldEdit = QTextEdit()
self.Mapper.addMapping(self.FirstFieldEdit, 0)
self.Mapper.addMapping(self.SecondFieldEdit, 1)
self.Mapper.addMapping(self.ThirdFieldEdit, 2)
self.Mapper.toFirst()
self.UpdateButton = QPushButton("Next")
self.UpdateButton.clicked.connect(self.DataModel.Update)
formLayout = QFormLayout()
formLayout.addRow("&First:", self.FirstFieldEdit)
formLayout.addRow("&Second:", self.SecondFieldEdit)
formLayout.addRow("&Third:", self.ThirdFieldEdit)
formLayout.addRow("", self.UpdateButton)
self.testTable = QTableView()
self.testTable.setModel(self.DataModel)
formLayout.addRow("Table:", self.testTable)
W = QWidget()
W.setLayout(formLayout)
self.setCentralWidget(W)
##############################################################################
if __name__ == "__main__":
app = QApplication(sys.argv)
MainWindow = TMainWindow()
MainWindow.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
QDataWidgetMapper
类旨在允许在模型中显示和编辑记录。但是,当请求编辑数据时,您的模型不会返回任何内容。所以一个简单的解决方案是:
def data(self, index, role=Qt.DisplayRole):
if index.isValid():
if role == Qt.DisplayRole or role == Qt.EditRole:
...
修改强>:
来自Qt Docs:
QDataWidgetMapper可用于通过映射创建数据感知小部件 它们是项目模型的部分。如果是,则部分是模型的列 方向是水平的(默认),否则是行。 [强调补充]
我建议你避免尝试编写一个自定义模型(除了最简单的情况,这是非常微不足道的),然后使用QStandardItemModel开始。