0

QSqlRelationalTableModel の行と列を交換する必要があります。たくさん検索した後、行と列を反転するための小さなプロキシモデルを書きました。

それは部分的に働いています。テーブル内の関係は解決されて表示されますが、それらを選択するためのドロップボックスが失われます。また、それらを更新するにはどうすればよいですか?

これは、動作を再現する小さな自己完結型スクリプトです。

私のエラーはどこですか?モデルのシグナルとスロットに関係があるのではないかと強く疑っていますが、どれをどのように再実装するかについてのヒントは見つかりませんでした。

行と列を交換する別の簡単な方法はありますか?

編集:委任モデルが完全に機能していないことを明確にするために、部分的に機能しているだけです。

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_())
4

1 に答える 1

4

#pyqt irc のフレンドリーな見知らぬ人に感謝します。これは解決しました。

答えは、デリゲートにも 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))
于 2015-03-09T15:54:49.113 に答える