簡體   English   中英

如何從pyqt中的qtableview中刪除行/行?

[英]How to delete row/rows from a qtableview in pyqt?

我正在為我的 qtableview 使用 QStandardItemModel。

import ui_my_viewlogs
import os
from PyQt4 import QtCore, QtGui

class my_viewlogs(QtGui.QDialog, ui_my_viewlogs.Ui_viewlogs):
    def __init__(self):
        super(my_viewlogs, self).__init__()
        self.setupUi(self)
        self.model = QtGui.QStandardItemModel()
        self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.header_names = ['abc', 'def', 'ghi', 'kjl', 'mno', 'pqr']
        self.model.setHorizontalHeaderLabels(self.header_names)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.setShowGrid(False)
        self.selectionModel = self.tableView.selectionModel()
        self.tableView.customContextMenuRequested.connect(self.open_menu)
        self.tableView.setModel(self.model)
        self.tableView.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)

    def open_menu(self, position):
        menu = QtGui.QMenu()
        remove_selected_item_icon = QtGui.QIcon()
        remove_selected_item_icon.addPixmap(QtGui.QPixmap(":/images      /Images/deleteSelected.png"), QtGui.QIcon.Normal, QtGui.QIcon.On)
        remove_selected_item = menu.addAction(remove_selected_item_icon, "Remove selected item(s) ")
        if action == remove_selected_item:           
            model = self.model
            indices = self.tableView.selectionModel().selectedRows() 
            for index in sorted(indices):
                model.removeRow(index.row(), QtCore.QModelIndex()) 

在這里,當我嘗試刪除選定的行(即 model.removeRow() )時,出現錯誤“TypeError:QAbstractItemModel.removeRow() 的參數 1 具有無效類型”。

我已經搜索了很多在 pyqt 的 qtableview 中刪除選定行/行的正確方法。 但是,我無法刪除選定的行。

您能否分享一個示例代碼,用於在 pyqt 的 qtableview 中刪除選定的行/行?

方法 model.removeRow(index.row()) 刪除選定的行。

model = self.model
    indices = self.tableView.selectionModel().selectedRows() 
    for index in sorted(indices):
        model.removeRow(index.row()) 

在索引變量中,我們獲得了選定的行,然后我們刪除了該行。

在我們選擇的 tableview 中刪除多行:

index_list = []                                                          
for model_index in self.tableView.selectionModel().selectedRows():       
    index = QtCore.QPersistentModelIndex(model_index)         
    index_list.append(index)                                             

for index in index_list:                                      
     self.model.removeRow(index.row())                                                               

如果有人在實施Anuj Bhasin's答案后仍在尋找答案,因為上述解決方案在許多情況下無法按預期工作。

原因:

  • 當您刪除行索引(例如[0,1,2] ),並且您從0 -> 1 -> 2開始刪除時,則只會刪除第 0 行和第 2 行!
  • 刪除第一個項目會將剩余的行向上移動,使row 1row 2 row 0分別為row 0row 1 ,因此當您下次刪除第 1 行時,第 2 行(以前)將被刪除,因為它現在是第 1 行。

我有一個解決方案:

傳遞要刪除的行,例如從 5 行刪除[0,3]

def setSel(selected: List[int], table_widget: QTableWidget):
    """
    Select all rows for the given index range
    """
    table_widget.setSelectionMode(QAbstractItemView.MultiSelection)
    for i in selected:
        table_widget.selectRow(i)

然后使用remove_row_all_table() : QTableWidget作為參數調用remove_row_all_table()

def remove_row_all_table(table_widget):
    """
    Select and Delete rows from table widget
    """
    table_widget: QTableWidget
    selected_rows = table_widget.selectionModel().selectedRows()
    if selected_rows:
        row_indices = []
        for row_index in selected_rows:
            row_indices.append(row_index.row())
        row_indices.sort(key=lambda x: -1 * x)
        print(row_indices)
        for row in row_indices:  # sorted in descending order
            print(f"row count:{table_widget.rowCount()}, deleting index:{row}")
            table_widget.removeRow(row)
    print()

這個答案的摘要是:您必須以相反的順序打開MultiSelection模式和Delete,即從較高的索引到較低的索引,這樣我在答案開頭提到的依賴就不會發生。

在 C++ 中:

QModelIndexList indices = myTable->selectionModel()->selectedRows();

for (int i=indices.count()-1; i>=0; --i)
{
    QModelIndex index = indices.at(i);
    myTable->removeRow(index.row());
}

您必須從列表的底部到頂部,否則您的索引將被搞砸。

這對我使用 reversed() 很好用。

        indices = self.tag_table.selectionModel().selectedRows()

        # Must delete in reverse order
        for each_row in reversed(sorted(indices)):
            self.tag_table.removeRow(each_row.row())

我知道這是一個較舊的問題,但我認為這更簡潔並且可以解決問題。

def delete_record1(self, model, view):
    """Delete rows with currently selected cells and/or selected rows of the model"""
    rows = [model_index.row() for model_index in view.selectedIndexes()]
    
    rows.sort(reverse=True)

    for i in rows:
        model.removeRow(i)
    
    model.submitAll()
    model.select()    

任何人都可以建議這種方法的陷阱是什么?

暫無
暫無

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

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