如何删除QTableView小部件中的多行?(How to delete multiple rows in a QTableView widget?)

系统教程 行业动态 更新时间:2024-06-14 16:57:17
如何删除QTableView小部件中的多行?(How to delete multiple rows in a QTableView widget?)

(我是一个PyQt初学者。)

我想通过按QPushButton删除QTableView小部件中的行。 该代码可以正常工作,但是,当我选择多行时,一行总是被忽略。

这是我到目前为止:

main.ui

<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>350</width> <height>239</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <widget class="QWidget" name="formLayoutWidget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>341</width> <height>231</height> </rect> </property> <layout class="QFormLayout" name="formLayout"> <item row="0" column="1"> <widget class="QPushButton" name="btnPopulate"> <property name="text"> <string>Populate Table</string> </property> </widget> </item> <item row="2" column="1"> <widget class="QTableView" name="tableView"> <property name="selectionBehavior"> <enum>QAbstractItemView::SelectRows</enum> </property> </widget> </item> <item row="1" column="1"> <widget class="QPushButton" name="btnDelete"> <property name="text"> <string>Delete Row(s)</string> </property> </widget> </item> </layout> </widget> </widget> <resources/> <connections/> </ui>

test.py

#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, os from PyQt5 import uic, QtWidgets from PyQt5.QtGui import QStandardItemModel from PyQt5.QtWidgets import QDialog, QComboBox, QApplication, QHeaderView class GUI(QDialog): def __init__(self): super(GUI, self).__init__() dirname = os.path.dirname(os.path.abspath(__file__)) uic.loadUi(os.path.join(dirname,'main.ui'), self) # buttons self.btnPopulate.clicked.connect(self.populate) self.btnDelete.clicked.connect(self.delete) # table model self.header = ['col1', 'col2', 'col3'] self.QSModel = QStandardItemModel() self.QSModel.setColumnCount(3) self.QSModel.setHorizontalHeaderLabels(self.header) self.tableView.setModel(self.QSModel) self.tableView.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) def populate(self): row = self.QSModel.rowCount() for x in range(7): self.QSModel.insertRow(row) self.QSModel.setData(self.QSModel.index(row, 0), 'data' + str(x)) self.QSModel.item(row, 0).setEditable(True) self.QSModel.setData(self.QSModel.index(row, 1), 'data' + str(x)) self.QSModel.item(row, 1).setEditable(True) self.QSModel.setData(self.QSModel.index(row, 2), 'data' + str(x)) self.QSModel.item(row, 1).setEditable(True) def delete(self): if self.tableView.selectionModel().hasSelection(): indexes = self.tableView.selectionModel().selectedRows() for index in sorted(indexes): print('Deleting row %d...' % index.row()) self.QSModel.removeRow(index.row()) else: print('No row selected!') if __name__ == '__main__': app = QApplication(sys.argv) window = GUI() window.show() sys.exit(app.exec_())

我有以下问题:

为什么当我选择多行时总是不会删除一行,并且需要更改哪些内容才能删除所有选定的行? 如何在删除完成后自动选择下一行,以便通过反复点击删除行按钮来删除整个表格? 有没有一种内置方法可以让我将QPushButton或其动作连接到DEL / BACKSPACE按键? 也就是说,我想要DEL / BACKSPACE按键来触发delete()。

(I'm a PyQt beginner.)

I want to delete rows in a QTableView widget by pressing a QPushButton. The code works fine with a single row, however, when I select multiple rows one row is always left out.

This is what I have so far:

main.ui

<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>Dialog</class> <widget class="QDialog" name="Dialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>350</width> <height>239</height> </rect> </property> <property name="windowTitle"> <string>Dialog</string> </property> <widget class="QWidget" name="formLayoutWidget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>341</width> <height>231</height> </rect> </property> <layout class="QFormLayout" name="formLayout"> <item row="0" column="1"> <widget class="QPushButton" name="btnPopulate"> <property name="text"> <string>Populate Table</string> </property> </widget> </item> <item row="2" column="1"> <widget class="QTableView" name="tableView"> <property name="selectionBehavior"> <enum>QAbstractItemView::SelectRows</enum> </property> </widget> </item> <item row="1" column="1"> <widget class="QPushButton" name="btnDelete"> <property name="text"> <string>Delete Row(s)</string> </property> </widget> </item> </layout> </widget> </widget> <resources/> <connections/> </ui>

test.py

#!/usr/bin/env python # -*- coding: utf-8 -*- import sys, os from PyQt5 import uic, QtWidgets from PyQt5.QtGui import QStandardItemModel from PyQt5.QtWidgets import QDialog, QComboBox, QApplication, QHeaderView class GUI(QDialog): def __init__(self): super(GUI, self).__init__() dirname = os.path.dirname(os.path.abspath(__file__)) uic.loadUi(os.path.join(dirname,'main.ui'), self) # buttons self.btnPopulate.clicked.connect(self.populate) self.btnDelete.clicked.connect(self.delete) # table model self.header = ['col1', 'col2', 'col3'] self.QSModel = QStandardItemModel() self.QSModel.setColumnCount(3) self.QSModel.setHorizontalHeaderLabels(self.header) self.tableView.setModel(self.QSModel) self.tableView.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents) def populate(self): row = self.QSModel.rowCount() for x in range(7): self.QSModel.insertRow(row) self.QSModel.setData(self.QSModel.index(row, 0), 'data' + str(x)) self.QSModel.item(row, 0).setEditable(True) self.QSModel.setData(self.QSModel.index(row, 1), 'data' + str(x)) self.QSModel.item(row, 1).setEditable(True) self.QSModel.setData(self.QSModel.index(row, 2), 'data' + str(x)) self.QSModel.item(row, 1).setEditable(True) def delete(self): if self.tableView.selectionModel().hasSelection(): indexes = self.tableView.selectionModel().selectedRows() for index in sorted(indexes): print('Deleting row %d...' % index.row()) self.QSModel.removeRow(index.row()) else: print('No row selected!') if __name__ == '__main__': app = QApplication(sys.argv) window = GUI() window.show() sys.exit(app.exec_())

I've got the following questions:

Why is always one row not deleted when I select multiple rows and what do I need to change to delete all selected rows? How do I automatically select the next row after the deletion is complete so that I could delete the whole table by repeatedly clicking the Delete Row(s) button? Is there a built-in method that allows me to either connect the QPushButton or its action to DEL/BACKSPACE key-presses? I.e., I want DEL/BACKSPACE key-presses to trigger delete().

最满意答案

为什么当我选择多行时总是不会删除一行,并且需要更改哪些内容才能删除所有选定的行?

这个问题是由于通过重置位置来删除一行造成的,例如,假设你删除了3,4,5,首先删除了3,然后4变成了3,并且5变成了4,然后你删除了4,删除了4这样的电流最初的4没有被删除。

QModelIndex是临时索引,如果位置发生更改,则不会通知它们,而是通知QPersistentModelIndex ,因此即使它发生更改,也必须使用它们来获取行。

def delete(self): if self.tableView.selectionModel().hasSelection(): indexes =[QPersistentModelIndex(index) for index in self.tableView.selectionModel().selectedRows()] for index in indexes: print('Deleting row %d...' % index.row()) self.QSModel.removeRow(index.row()) else: print('No row selected!')

如何在删除完成后自动选择下一行,以便通过反复点击删除行按钮来删除整个表格?

要选择一个新行,您必须通过QTableView的setCurrentIndex()方法将该行的某些项目设置为活动状态,在本例中,我计算最后一行,并使用该行获得下一行项目的QPersistentModelIndex ,删除I将其转换为QModelIndex并在之前的方法中使用它。

def delete(self): if self.tableView.selectionModel().hasSelection(): indexes =[QPersistentModelIndex(index) for index in self.tableView.selectionModel().selectedRows()] maxrow = max(indexes, key=lambda x: x.row()).row() next_ix = QPersistentModelIndex(self.QSModel.index(maxrow+1, 0)) for index in indexes: print('Deleting row %d...' % index.row()) self.QSModel.removeRow(index.row()) self.tableView.setCurrentIndex(QModelIndex(next_ix)) else: print('No row selected!')

有没有一种内置方法可以让我将QPushButton或其动作连接到DEL / BACKSPACE按键? 也就是说,我想要DEL / BACKSPACE按键来触发delete()。

要获得键盘事件,你必须重写keyPressEvent方法,这个事件发生为一个QKeyEvent对象,它有一个返回按键的键方法,验证它是否是所需的键,如果是,则调用delete()

def keyPressEvent(self, event): if event.key() in (Qt.Key_Backspace, Qt.Key_Delete): self.delete() QDialog.keyPressEvent(self, event)

Why is always one row not deleted when I select multiple rows and what do I need to change to delete all selected rows?

The problem is caused by removing a row by resetting the positions, for example, say that you remove 3,4,5, first remove 3, then 4 becomes 3, and 5 becomes 4, then you eliminate 4, remove the 4 current so that the initial 4 is not deleted.

QModelIndex are temporary indexes that are not notified if the positions change, instead QPersistentModelIndex if they are notified so you must use them to get the row even if it changes.

def delete(self): if self.tableView.selectionModel().hasSelection(): indexes =[QPersistentModelIndex(index) for index in self.tableView.selectionModel().selectedRows()] for index in indexes: print('Deleting row %d...' % index.row()) self.QSModel.removeRow(index.row()) else: print('No row selected!')

How do I automatically select the next row after the deletion is complete so that I could delete the whole table by repeatedly clicking the Delete Row(s) button?

to select a new row you must set some item of that row as active through the setCurrentIndex() method of QTableView, in this example I calculate the last row and with that I get the QPersistentModelIndex of an item of the next row, after deleting I convert it to QModelIndex and I use it in the previous method.

def delete(self): if self.tableView.selectionModel().hasSelection(): indexes =[QPersistentModelIndex(index) for index in self.tableView.selectionModel().selectedRows()] maxrow = max(indexes, key=lambda x: x.row()).row() next_ix = QPersistentModelIndex(self.QSModel.index(maxrow+1, 0)) for index in indexes: print('Deleting row %d...' % index.row()) self.QSModel.removeRow(index.row()) self.tableView.setCurrentIndex(QModelIndex(next_ix)) else: print('No row selected!')

Is there a built-in method that allows me to either connect the QPushButton or its action to DEL/BACKSPACE key-presses? I.e., I want DEL/BACKSPACE key-presses to trigger delete().

to get the keyboard events you must overwrite the keyPressEvent method, this event happens as a QKeyEvent object that has a key method that returns the key pressed, verify if it is the desired key and if it is, then call delete()

def keyPressEvent(self, event): if event.key() in (Qt.Key_Backspace, Qt.Key_Delete): self.delete() QDialog.keyPressEvent(self, event)

更多推荐

本文发布于:2023-04-12 20:10:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/6b0f269d571ee619f8ec3ac644511b3f.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:部件   delete   QTableView   widget   rows

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!