Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQt5:使用QTableView.setSortingEnabled和QSortFilterProxyModel时的幻影列_Python_Qt_Pyqt_Pyqt5_Qtableview - Fatal编程技术网

Python PyQt5:使用QTableView.setSortingEnabled和QSortFilterProxyModel时的幻影列

Python PyQt5:使用QTableView.setSortingEnabled和QSortFilterProxyModel时的幻影列,python,qt,pyqt,pyqt5,qtableview,Python,Qt,Pyqt,Pyqt5,Qtableview,我有一个定制的Qt表模型,它允许用户在创建列和行之后添加列和行。我试图使用QSortFilterProxyModel/QTableView设置显示此表,但当我尝试在表视图上启用排序时,出现了奇怪的行为。“我的视图”启动并正确显示添加的数据: 但是,当我单击其中一个列标题(进行排序)时,虚拟列将添加到视图中 以前有没有人见过这个或者知道发生了什么?诚然,我还是一个Qt的新手,所以也许我只是用错误的方式来处理这个问题。谢谢 # -*- mode:python; mode:auto-fill; f

我有一个定制的Qt表模型,它允许用户在创建列和行之后添加列和行。我试图使用QSortFilterProxyModel/QTableView设置显示此表,但当我尝试在表视图上启用排序时,出现了奇怪的行为。“我的视图”启动并正确显示添加的数据:

但是,当我单击其中一个列标题(进行排序)时,虚拟列将添加到视图中

以前有没有人见过这个或者知道发生了什么?诚然,我还是一个Qt的新手,所以也许我只是用错误的方式来处理这个问题。谢谢

# -*- mode:python; mode:auto-fill; fill-column:79; coding:utf-8 -*-

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

# =====================================================================
# =====================================================================
class SimpleProxyModel(QSortFilterProxyModel):
    def filterAcceptsColumn(self, col, index):
        return True

# =====================================================================
# =====================================================================
class SimpleModel(QAbstractTableModel):

    def __init__(self):
        super(SimpleModel, self).__init__()
        self._data = {}

    def rowCount(self, index=QModelIndex()):
        if len(self._data.values()) > 0:
            return len(self._data.values()[0])
        else:
            return 0

    def columnCount(self, index=QModelIndex()):
        return len(self._data.keys())

    def data( self, index, role = Qt.DisplayRole ):
        row, col = index.row(), index.column()

        if ( not index.isValid() or
             not ( 0 <= row < self.rowCount() ) or
             not ( 0 <= col < self.columnCount() ) ):
            return QVariant()

        if role == Qt.DisplayRole:
            return QVariant( self._data[col][row] )

        return QVariant()

    def addData( self, col, val):

        new_col = False
        # Turn on flag for new column
        if col not in self._data.keys():
            new_col = True

        if new_col:
            self.beginInsertColumns(QModelIndex(), self.columnCount(),self.columnCount())
            # Catch this column up with the others by adding blank rows
            self._data[col] = [""] * self.rowCount()

        self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
        # Add data to each column, either the value specified or a blank
        for i in range(self.columnCount()):
            if i == col:
                self._data[i].append(val)
            else:
                self._data[i].append( "" )
        self.endInsertRows()

        if new_col:
            self.endInsertColumns()


# =====================================================================
# =====================================================================
class SimpleView(QWidget):

    def __init__(self, parent=None):

        super(SimpleView, self).__init__(parent)

        self._mainmodel = None
        self._proxymodel = None
        self._tableview = QTableView()
        self._tableview.setSortingEnabled(True)

        layout = QVBoxLayout()
        layout.addWidget( self._tableview )

        self.setLayout(layout)

    def setModel(self, model):

        self._mainmodel = model
        proxy = SimpleProxyModel()
        proxy.setSourceModel(model)
        self._tableview.setModel(proxy)

# =====================================================================
# =====================================================================
app = QApplication([])

v = SimpleView()
m = SimpleModel()
v.setModel( m )

m.addData(0,1)
m.addData(0,2)
m.addData(1,3)

v.show()
app.exec_()
#-*-模式:python;模式:自动填充;填充栏:79;编码:utf-8-*-
从PyQt5.QtCore导入*
从PyQt5.QtWidgets导入*
# =====================================================================
# =====================================================================
类SimpleProxyModel(QSortFilterProxyModel):
def过滤器AcceptsColumn(自身、列、索引):
返回真值
# =====================================================================
# =====================================================================
类SimpleModel(QAbstractTableModel):
定义初始化(自):
super(SimpleModel,self)。\uuuu init\uuuuu()
self._data={}
def行数(self,index=QModelIndex()):
如果len(self.\u data.values())>0:
返回len(self.\u data.values()[0])
其他:
返回0
def columnCount(self,index=QModelIndex()):
返回len(self.\u data.keys())
def数据(self,index,role=Qt.DisplayRole):
行,列=index.row(),index.column()
如果(不是index.isValid()或

不是(0Qt文档对此相当清楚。您必须在之后和之后调用

上面最后一个链接中最相关的一点是:

注意:此函数发出columnsAboutToBeInserted()信号,该信号 在插入数据之前,必须处理连接的视图(或代理)。 否则,视图可能最终处于无效状态


因此,您必须调用
endInsertColum()
在开始任何其他插入/删除之前。

问题似乎出现在我的
SimpleModel.addData
方法中,并且与我嵌套列和行插入的方式有关。如果将此方法更改为先插入新列,然后插入新行,则不会显示虚拟列

def addData( self, col, val):                                               

    if col not in self._data.keys():                                        
        self.beginInsertColumns(QModelIndex(), self.columnCount(),self.columnCount())
        # Catch this column up with the others by adding blank rows         
        self._data[col] = [""] * self.rowCount()                            
        self.endInsertColumns()                                             

    self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())   
    # Add data to each column, either the value specified or a blank        
    for i in range(self.columnCount()):                                     
        if i == col:                                                        
            self._data[i].append(val)                                       
        else:                                                               
            self._data[i].append( "" )                                      
    self.endInsertRows()

谢谢@tmoreau,完成了。在python方面,你似乎是个巫师。你做过自由职业吗?@JokerMartini。谢谢你的提问,但由于其他原因,我现在无法从事自由职业。这真是一个令人沮丧的问题。我有一个feq python需要帮助的东西,我希望你能帮我。我把它作为一个问题发布就在这里。