我需要交换QSqlRelationalTableModel的行和列。经过大量的搜索,我写了一个小代理模型来翻转行和列。
部分有效。表中的关系已解决并显示,但选择它们的Dropbox会丢失。另外,我如何让它们更新?
这是一个重现行为的小型自包含脚本。
我的错误在哪里?我强烈怀疑它与模型的信号和插槽有关,但我还没有找到任何提示,以及如何重新实现它们。
还有另一种更简单的方法来交换行和列吗?
编辑:澄清委托模式并不完全不能正常工作。
from PySide import QtCore, QtGui, QtSql
from PySide.QtCore import Qt, QModelIndex
from PySide.QtGui import QAbstractProxyModel, QWidget, QHBoxLayout, QTableView
from PySide.QtSql import QSqlRelationalDelegate
class FlipProxyModel(QAbstractProxyModel):
def __init__(self, parent=None):
super(FlipProxyModel, self).__init__(parent)
def mapFromSource(self, index):
return self.createIndex(index.column(), index.row())
def mapToSource(self, index):
return self.sourceModel().index(index.column(), index.row(), QModelIndex())
def columnCount(self, parent):
return self.sourceModel().rowCount(QModelIndex())
def rowCount(self, parent):
return self.sourceModel().columnCount(QModelIndex())
def index(self, row, column, parent):
return self.createIndex(row, column)
def parent(self, index):
# tables have no parent object so return empty
return QModelIndex()
def data(self, index, role):
return self.sourceModel().data(self.mapToSource(index), role)
def headerData(self, section, orientation, role):
if orientation == Qt.Horizontal:
return self.sourceModel().headerData(section, Qt.Vertical, role)
if orientation == Qt.Vertical:
return self.sourceModel().headerData(section, Qt.Horizontal, role)
def createConnection():
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName(":memory:")
if not db.open():
print 'fatal'
return False
return True
def createView(title, model):
view = QtGui.QTableView()
view.setModel(model)
view.setItemDelegate(QtSql.QSqlRelationalDelegate(view))
view.setWindowTitle(title)
return view
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
if not createConnection():
sys.exit(1)
# createRelationalTables()
query = QtSql.QSqlQuery()
query.exec_("create table employee(id int, name varchar(20), city int, country int)")
query.exec_("insert into employee values(1, 'Espen', 5000, 47)")
query.exec_("insert into employee values(2, 'Harald', 80000, 49)")
query.exec_("insert into employee values(3, 'Sam', 100, 41)")
query.exec_("create table city(id int, name varchar(20))")
query.exec_("insert into city values(100, 'San Jose')")
query.exec_("insert into city values(5000, 'Oslo')")
query.exec_("insert into city values(80000, 'Munich')")
query.exec_("create table country(id int, name varchar(20))")
query.exec_("insert into country values(41, 'USA')")
query.exec_("insert into country values(47, 'Norway')")
query.exec_("insert into country values(49, 'Germany')")
model = QtSql.QSqlRelationalTableModel()
model.setTable("employee")
model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
model.setRelation(2, QtSql.QSqlRelation('city', 'id', 'name'))
model.setRelation(3, QtSql.QSqlRelation('country', 'id', 'name'))
model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
model.setHeaderData(1, QtCore.Qt.Horizontal, "Name")
model.setHeaderData(2, QtCore.Qt.Horizontal, "City")
model.setHeaderData(3, QtCore.Qt.Horizontal, "Country")
model.select()
proxy = FlipProxyModel()
proxy.setSourceModel(model)
w = QWidget()
layout = QHBoxLayout(w)
view = QTableView()
view.setModel(model)
view.setItemDelegate(QSqlRelationalDelegate(view))
layout.addWidget(view)
view2 = QTableView()
view2.setModel(proxy)
view2.setItemDelegate(QSqlRelationalDelegate(view2))
layout.addWidget(view2)
w.show()
sys.exit(app.exec_())
答案 0 :(得分:0)
答案是代理人还需要一个proxymodel类。
该课程如下:class FlipProxyDelegate(QSqlRelationalDelegate):
def createEditor(self, parent, option, index):
proxy = index.model()
base_index = proxy.mapToSource(index)
return super(FlipProxyDelegate, self).createEditor(parent, option, base_index)
def setEditorData(self, editor, index):
proxy = index.model()
base_index = proxy.mapToSource(index)
return super(FlipProxyDelegate, self).setEditorData(editor, base_index)
def setModelData(self, editor, model, index):
base_model = model.sourceModel()
base_index = model.mapToSource(index)
return super(FlipProxyDelegate, self).setModelData(editor, base_model, base_index)
使用然后将代理替换为:
view.setItemDelegate(FlipProxyDelegate(self.tableView))