簡體   English   中英

PyQt5:使用QTableView.setSortingEnabled和QSortFilterProxyModel時的幻像列

[英]PyQt5: phantom columns when using QTableView.setSortingEnabled and QSortFilterProxyModel

我有一個自定義的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_()

Qt文檔對此非常清楚。 你必須調用endInsertRowsbeginInsertRowsendInsertColumnsbeginInsertColumns

上面最后一個鏈接中最相關的一點是:

注意:此函數發出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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM