如何将 QTableView 项目的方向从垂直更改为水平?
How to change QTableView items Orientation from Vertical to Horizontal?
下面的代码创建了一个 window,其中放置了两个 QTableView side-by-side:
left-side TableView 链接到 QAbstractTableModel
。根据 Model.data()
中定义的逻辑,tableView 的项目是垂直放置的。
right-side TableView 链接到 QSortFilterProxyModel
。我想用它来将垂直的 TableView 项目放置更改为水平。
请 post 您就如何实现这一目标提出建议。如果更改项目方向的解决方案不需要 ProxyModel 也没关系......只要它有效!
稍后发布源代码。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
if row<len(self.items):
return QVariant(self.items[row])
else:
return QVariant()
class Proxy(QSortFilterProxyModel):
def __init__(self):
super(Proxy, self).__init__()
def rowCount(self, parent):
return 1
def columnCount(self, parent):
sourceModel=self.sourceModel()
return len(sourceModel.items)
def filterAcceptsRow(self, row, parent):
sourceModel=self.sourceModel()
sourceModelIndex=sourceModel.index(row, 0, QModelIndex())
sourceModelIndexName=sourceModel.data(sourceModelIndex, Qt.DisplayRole).toString()
return True
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
tablemodel=Model(self)
proxy=Proxy()
proxy.setSourceModel(tablemodel)
tableviewA=QTableView()
tableviewA.setModel(tablemodel)
tableviewB=QTableView()
tableviewB.setModel(proxy)
layout = QHBoxLayout(self)
layout.addWidget(tableviewA)
layout.addWidget(tableviewB)
self.setLayout(layout)
def test(self, arg):
print arg
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
一个有趣的作业...
class Model2(QAbstractTableModel):
def __init__(self, model, parent=None):
self.model = model
QAbstractTableModel.__init__(self, parent)
def rowCount(self):
return self.model.columnCount()
def columnCount(self):
return self.model.rowCount()
def data(self, a, b):
return self.model.data(b, a)
这是使用代理将项目从垂直方向重新定向为水平方向的有效解决方案。
诀窍是通过在代理模型下声明它来覆盖源模型的 .data()
方法。在 Proxy 上声明时,它优先于源模型的 .data()
方法:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return len(self.items)
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
if row<len(self.items):
return QVariant(self.items[row])
else:
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
row = index.row()
self.items[row]=value
return True
return False
class Proxy(QSortFilterProxyModel):
def __init__(self):
super(Proxy, self).__init__()
def rowCount(self, parent):
return 1
def columnCount(self, parent):
sourceModel=self.sourceModel()
return len(sourceModel.items)
def filterAcceptsRow(self, row, parent):
sourceModel=self.sourceModel()
sourceModelIndex=sourceModel.index(row, 0, QModelIndex())
sourceModelIndexName=sourceModel.data(sourceModelIndex, Qt.DisplayRole).toString()
return True
def data(self, index, role):
sourceModel=self.sourceModel()
items=sourceModel.items
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
column=index.column()
if column<len(items):
return QVariant(items[column])
else:
return QVariant()
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
tablemodel=Model(self)
proxy=Proxy()
proxy.setSourceModel(tablemodel)
tableviewA=QTableView()
tableviewA.setModel(tablemodel)
tableviewB=QTableView()
tableviewB.setModel(proxy)
layout = QHBoxLayout(self)
layout.addWidget(tableviewA)
layout.addWidget(tableviewB)
self.setLayout(layout)
def test(self, arg):
print arg
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
这是受 mdurant 答案启发的第二个解决方案。我在这里起诉两个 QAbstractTableModel
。第二个模型查询第一个模型self.items
数据变量。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Horizontal(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
self.childModel=None
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
if row<len(self.items):
return QVariant(self.items[row])
else:
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
row = index.row()
self.items[row]=value
if self.childModel: self.childModel.reset()
return True
return False
class Vertical(QAbstractTableModel):
def __init__(self, items=None, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = items
def rowCount(self, parent):
return 1
def columnCount(self, parent):
return len(self.items)
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
column=index.column()
if column<len(self.items):
return QVariant(self.items[column])
else:
return QVariant()
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
modelV=Horizontal(self)
tableviewA=QTableView()
tableviewA.setModel(modelV)
modelH=Vertical(modelV.items)
modelV.childModel=modelH
tableviewB=QTableView()
tableviewB.setModel(modelH)
layout = QHBoxLayout(self)
layout.addWidget(tableviewA)
layout.addWidget(tableviewB)
self.setLayout(layout)
def test(self, arg):
print arg
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
下面的代码创建了一个 window,其中放置了两个 QTableView side-by-side:
left-side TableView 链接到 QAbstractTableModel
。根据 Model.data()
中定义的逻辑,tableView 的项目是垂直放置的。
right-side TableView 链接到 QSortFilterProxyModel
。我想用它来将垂直的 TableView 项目放置更改为水平。
请 post 您就如何实现这一目标提出建议。如果更改项目方向的解决方案不需要 ProxyModel 也没关系......只要它有效!
稍后发布源代码。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
if row<len(self.items):
return QVariant(self.items[row])
else:
return QVariant()
class Proxy(QSortFilterProxyModel):
def __init__(self):
super(Proxy, self).__init__()
def rowCount(self, parent):
return 1
def columnCount(self, parent):
sourceModel=self.sourceModel()
return len(sourceModel.items)
def filterAcceptsRow(self, row, parent):
sourceModel=self.sourceModel()
sourceModelIndex=sourceModel.index(row, 0, QModelIndex())
sourceModelIndexName=sourceModel.data(sourceModelIndex, Qt.DisplayRole).toString()
return True
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
tablemodel=Model(self)
proxy=Proxy()
proxy.setSourceModel(tablemodel)
tableviewA=QTableView()
tableviewA.setModel(tablemodel)
tableviewB=QTableView()
tableviewB.setModel(proxy)
layout = QHBoxLayout(self)
layout.addWidget(tableviewA)
layout.addWidget(tableviewB)
self.setLayout(layout)
def test(self, arg):
print arg
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
一个有趣的作业...
class Model2(QAbstractTableModel):
def __init__(self, model, parent=None):
self.model = model
QAbstractTableModel.__init__(self, parent)
def rowCount(self):
return self.model.columnCount()
def columnCount(self):
return self.model.rowCount()
def data(self, a, b):
return self.model.data(b, a)
这是使用代理将项目从垂直方向重新定向为水平方向的有效解决方案。
诀窍是通过在代理模型下声明它来覆盖源模型的 .data()
方法。在 Proxy 上声明时,它优先于源模型的 .data()
方法:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return len(self.items)
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
if row<len(self.items):
return QVariant(self.items[row])
else:
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
row = index.row()
self.items[row]=value
return True
return False
class Proxy(QSortFilterProxyModel):
def __init__(self):
super(Proxy, self).__init__()
def rowCount(self, parent):
return 1
def columnCount(self, parent):
sourceModel=self.sourceModel()
return len(sourceModel.items)
def filterAcceptsRow(self, row, parent):
sourceModel=self.sourceModel()
sourceModelIndex=sourceModel.index(row, 0, QModelIndex())
sourceModelIndexName=sourceModel.data(sourceModelIndex, Qt.DisplayRole).toString()
return True
def data(self, index, role):
sourceModel=self.sourceModel()
items=sourceModel.items
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
column=index.column()
if column<len(items):
return QVariant(items[column])
else:
return QVariant()
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
tablemodel=Model(self)
proxy=Proxy()
proxy.setSourceModel(tablemodel)
tableviewA=QTableView()
tableviewA.setModel(tablemodel)
tableviewB=QTableView()
tableviewB.setModel(proxy)
layout = QHBoxLayout(self)
layout.addWidget(tableviewA)
layout.addWidget(tableviewB)
self.setLayout(layout)
def test(self, arg):
print arg
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
这是受 mdurant 答案启发的第二个解决方案。我在这里起诉两个 QAbstractTableModel
。第二个模型查询第一个模型self.items
数据变量。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class Horizontal(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row0_Column1','Row0_Column2']
self.childModel=None
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent):
return len(self.items)
def columnCount(self, parent):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
row=index.row()
if row<len(self.items):
return QVariant(self.items[row])
else:
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
row = index.row()
self.items[row]=value
if self.childModel: self.childModel.reset()
return True
return False
class Vertical(QAbstractTableModel):
def __init__(self, items=None, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = items
def rowCount(self, parent):
return 1
def columnCount(self, parent):
return len(self.items)
def data(self, index, role):
if not index.isValid(): return QVariant()
elif role != Qt.DisplayRole:
return QVariant()
column=index.column()
if column<len(self.items):
return QVariant(self.items[column])
else:
return QVariant()
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
modelV=Horizontal(self)
tableviewA=QTableView()
tableviewA.setModel(modelV)
modelH=Vertical(modelV.items)
modelV.childModel=modelH
tableviewB=QTableView()
tableviewB.setModel(modelH)
layout = QHBoxLayout(self)
layout.addWidget(tableviewA)
layout.addWidget(tableviewB)
self.setLayout(layout)
def test(self, arg):
print arg
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())