2015-01-16 72 views
1

下面的代码创建放置并排侧的两个QTableViews的窗口:如何更改QTableView项目从垂直到水平的方向?

enter image description here

左侧的TableView中被链接到QAbstractTableModel。根据Model.data()中定义的逻辑,tableView的项目是垂直放置的。

右侧的TableView链接到QSortFilterProxyModel。我想用它来将垂直的TableView项目放置更改为水平。

请发表您的建议,以了解如何实现。如果更改项目方向的解决方案不需要ProxyModel,只要它可以正常工作就可以了!

SOURCE CODE POSTED LATER。

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_()) 
+0

有一个在C++类似的解决方案在http://stackoverflow.com/questions/21653253/how-to-change-orientation-of-qt-tableview – savolai

回答

2

一个有趣的任务......

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) 
+0

谢谢!请您发布整个CD。我很难实现'Model2()'代码... – alphanumeric

+0

对不起,我忘了发布源代码示例。它现在附在原始问题下! – alphanumeric

0

下面是使用代理服务器从垂直的项目重新定位为水平的工作方案。

诀窍是通过在Proxy模型下声明它来覆盖soruce模型的.data()方法。当代理声明它需要优先于源模型的方法.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_()) 
相关问题