如何获取检查的行QtableWidget

Posted

技术标签:

【中文标题】如何获取检查的行QtableWidget【英文标题】:how to get checked rows QtableWidget 【发布时间】:2021-07-24 14:46:42 【问题描述】:

我有这个代码。我想在单击删除按钮时删除勾选处于活动状态的任何行

from main import Ui_MainWindow
from PyQt5 import QtWidgets
from  PyQt5.QtCore import Qt

def set_cell_elements(rows, l):
    ui.tableWidget.setRowCount(len(rows))
    ui.tableWidget.setVerticalHeaderLabels(rows)
    ui.tableWidget.verticalHeader().setDefaultAlignment(Qt.AlignVCenter)
    ui.tableWidget.horizontalHeader().setDefaultAlignment(Qt.AlignCenter)

    for r in range(0, len(l)):
        for i in range (0, len(l[r])) :
            text = l[r][i]
            ui.tableWidget.setItem(r, i, QtWidgets.QTableWidgetItem(str(text)))
            ui.tableWidget.item(r, i).setTextAlignment(Qt.AlignCenter)
            item = ui.tableWidget.item(r, 0)
            item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            item.setCheckState(Qt.Unchecked)
            item.checkState()
            table_ = ui.tableWidget.horizontalHeader()
            table_.setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents)

def delete_button():
    pass

import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
#=====================
rows = ['a', 'b', 'c', 'd', 'e', 'f']
l = [['Wade', 'Wade', 'Seth', 'Ivan', 'Riley'],
        ['Gilbert', 'Jorge', 'Dan', 'Brian', 'Roberto'],
        ['Ramon', 'Liam', 'Miles', 'Nathaniel', 'Lewis'],
        ['Ethan', 'Milton', 'Joshua', 'Claude', 'Glen'],
        ['Harvey', 'Blake', 'Antonio', 'Connor', 'Julian'],
        ['Aidan', 'Harold', 'Conner', 'Peter', 'Hunter']]

set_cell_elements(rows, l)
ui.delete_button.clicked.connect(delete_button)
MainWindow.show()
sys.exit(app.exec_())

我没有解决方案来获取勾选处于活动状态的行,您能帮帮我吗!?请

【问题讨论】:

为了以后参考,请不要因为一个帖子被关闭就删除它(关闭并不意味着删除,它们可以再次打开),而是编辑它并提供所要求的内容。 你已经在使用checkState()(即使它在那里什么都不做),你为什么不在delete_button函数中使用它呢? 如果启用行检查,checkState()的输出是2,但是我用同样的方法尝试删除数据时,输出是0。我是初学者,我做不到解决问题,我说可能方法不对,还有另一种解决方案-@musicamante 您是如何“尝试删除数据”的?另外,您是说要删除一行,而不是删除数据,这是两件不同的事情。无论您尝试了什么,请edit您的帖子并向我们展示,以便我们正确指导您,解释您做错了什么并向您展示可能的解决方案。 哦,对不起。我的错误是我写了这样的代码 if item.checkstate() is True: 因为它的值等于 2,所以这个条件不适用,我错了,我一直认为他假设大于 0 的数字为真。 【参考方案1】:

欢迎来到 ***!您的问题中有一些缺失的信息可以帮助您解决问题。我只能猜测您的代码中缺少的部分。

我猜您已经使用 Qt Designer 以图形方式创建您的 UI。我会假设你的 UI 看起来像这样:

编译后给出:

main.py

​​>
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'Ui_MainWindow.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(19, 16, 761, 521))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.delete_button = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.delete_button.setObjectName("delete_button")
        self.verticalLayout.addWidget(self.delete_button)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.tableWidget = QtWidgets.QTableWidget(self.verticalLayoutWidget)
        self.tableWidget.setBaseSize(QtCore.QSize(0, 0))
        self.tableWidget.setRowCount(6)
        self.tableWidget.setColumnCount(5)
        self.tableWidget.setObjectName("tableWidget")
        self.verticalLayout_2.addWidget(self.tableWidget)
        self.verticalLayout.addLayout(self.verticalLayout_2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 24))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.delete_button.setText(_translate("MainWindow", "Delete selected rows"))

最小的更改解决方案是:

解决方案 1.py

​​>
from main import Ui_MainWindow
from PyQt5 import QtWidgets
from  PyQt5.QtCore import Qt

def set_cell_elements(rows, l):
    ui.tableWidget.setRowCount(len(rows))
    ui.tableWidget.setVerticalHeaderLabels(rows)
    ui.tableWidget.verticalHeader().setDefaultAlignment(Qt.AlignVCenter)
    ui.tableWidget.horizontalHeader().setDefaultAlignment(Qt.AlignCenter)

    for r in range(0, len(l)):
        for i in range (0, len(l[r])) :
            text = l[r][i]
            ui.tableWidget.setItem(r, i, QtWidgets.QTableWidgetItem(str(text)))
            ui.tableWidget.item(r, i).setTextAlignment(Qt.AlignCenter)
            item = ui.tableWidget.item(r, 0)
            item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            item.setCheckState(Qt.Unchecked)
            item.checkState()
            table_ = ui.tableWidget.horizontalHeader()
            table_.setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents)

def delete_button():
    for r in range(ui.tableWidget.rowCount(), 0, -1):
        item = ui.tableWidget.item(r - 1, 0)
        if item.checkState() == Qt.Checked:
            ui.tableWidget.removeRow(r - 1)

import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
#=====================
rows = ['a', 'b', 'c', 'd', 'e', 'f']
l = [['Wade', 'Wade', 'Seth', 'Ivan', 'Riley'],
        ['Gilbert', 'Jorge', 'Dan', 'Brian', 'Roberto'],
        ['Ramon', 'Liam', 'Miles', 'Nathaniel', 'Lewis'],
        ['Ethan', 'Milton', 'Joshua', 'Claude', 'Glen'],
        ['Harvey', 'Blake', 'Antonio', 'Connor', 'Julian'],
        ['Aidan', 'Harold', 'Conner', 'Peter', 'Hunter']]

set_cell_elements(rows, l)
ui.delete_button.clicked.connect(delete_button)
MainWindow.show()
sys.exit(app.exec_())


但是可以对您的代码进行更多的清理和简化:

解决方案 2.py

​​>
from main import Ui_MainWindow
from PyQt5 import QtWidgets

from PyQt5.QtCore import Qt

def set_cell_elements(row_headers, data_body):
    ui.tableWidget.setRowCount(len(row_headers))
    ui.tableWidget.setVerticalHeaderLabels(row_headers)
    ui.tableWidget.verticalHeader().setDefaultAlignment(Qt.AlignVCenter)
    ui.tableWidget.horizontalHeader().setDefaultAlignment(Qt.AlignCenter)

    for (row_number, current_row) in enumerate(data_body):
        for (column_number, current_text) in enumerate(current_row):
            ui.tableWidget.setItem(
                row_number, column_number, 
                QtWidgets.QTableWidgetItem(str(current_text))
            )
            ui.tableWidget.item(row_number, column_number).setTextAlignment(Qt.AlignCenter)
            row_header = ui.tableWidget.horizontalHeader()
            row_header.setSectionResizeMode(column_number, QtWidgets.QHeaderView.ResizeToContents)
        item = ui.tableWidget.item(row_number, 0)
        item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
        item.setCheckState(Qt.Unchecked)
 
def delete_button_action():    
    for current_row in range(ui.tableWidget.rowCount() - 1, -1, -1):
        first_item = ui.tableWidget.item(current_row, 0)
        state_current_row = first_item.checkState()
        if state_current_row == Qt.Checked:
            ui.tableWidget.removeRow(current_row)
    
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)

row_headers = ('a', 'b', 'c', 'd', 'e', 'f')
data_body = (
    ('Wade', 'Wade', 'Seth', 'Ivan', 'Riley'),
    ('Gilbert', 'Jorge', 'Dan', 'Brian', 'Roberto'),
    ('Ethan', 'Milton', 'Joshua', 'Claude', 'Glen'),
    ('Ramon', 'Liam', 'Miles', 'Nathaniel', 'Lewis'),
    ('Harvey', 'Blake', 'Antonio', 'Connor', 'Julian'),
    ('Aidan', 'Harold', 'Conner', 'Peter', 'Hunter')
)

set_cell_elements(row_headers, data_body)
ui.delete_button.clicked.connect(delete_button_action)
MainWindow.show()
sys.exit(app.exec_())


但是您可以以更面向对象的方式对此进行编码。这样,只要您提供包含的小部件及其初始数据,您就可以将其插入 UI 中的任何位置,它就会自行处理:

解决方案 3.py

​​>
import sys
from main import Ui_MainWindow
from PyQt5 import QtWidgets

from PyQt5.QtCore import Qt

class Simple_table_editor(Ui_MainWindow):

    def __init__(self, parent, row_headers, initial_data):
        super().__init__()
        self.setupUi(parent)
        self.tableWidget.setRowCount(len(row_headers))
        self.tableWidget.setVerticalHeaderLabels(row_headers)
        self.tableWidget.verticalHeader().setDefaultAlignment(Qt.AlignVCenter)
        self.tableWidget.horizontalHeader().setDefaultAlignment(Qt.AlignCenter)

        for (row_number, current_row) in enumerate(initial_data):
            for (column_number, current_text) in enumerate(current_row):
                self.tableWidget.setItem(
                    row_number, column_number, 
                    QtWidgets.QTableWidgetItem(str(current_text))
                )
                self.tableWidget.item(row_number, column_number).setTextAlignment(Qt.AlignCenter)
                row_header = self.tableWidget.horizontalHeader()
                row_header.setSectionResizeMode(column_number, QtWidgets.QHeaderView.ResizeToContents)
            item = self.tableWidget.item(row_number, 0)
            item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            item.setCheckState(Qt.Unchecked)
        
        self.delete_button.clicked.connect(self.delete_button_action)

    def delete_button_action(self):    
        for current_row in range(self.tableWidget.rowCount() - 1, -1, -1):
            first_item = self.tableWidget.item(current_row, 0)
            state_current_row = first_item.checkState()
            if state_current_row == Qt.Checked:
                self.tableWidget.removeRow(current_row)

row_headers = ('a', 'b', 'c', 'd', 'e', 'f')
data_body = (
    ('Wade', 'Wade', 'Seth', 'Ivan', 'Riley'),
    ('Gilbert', 'Jorge', 'Dan', 'Brian', 'Roberto'),
    ('Ethan', 'Milton', 'Joshua', 'Claude', 'Glen'),
    ('Ramon', 'Liam', 'Miles', 'Nathaniel', 'Lewis'),
    ('Harvey', 'Blake', 'Antonio', 'Connor', 'Julian'),
    ('Aidan', 'Harold', 'Conner', 'Peter', 'Hunter')
)

app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
table_editor = Simple_table_editor(MainWindow, row_headers, data_body)
MainWindow.show()
sys.exit(app.exec_())

如果我的猜测是错误的,而您打算做其他事情,请告诉我们更多细节。

【讨论】:

以上是关于如何获取检查的行QtableWidget的主要内容,如果未能解决你的问题,请参考以下文章

检查 CodeIgniter 中受影响的行数

Kotlin Exposed 获取更新的行数

如何使用 Swift 从 CoreData sqlite 表中获取特定的行数据

如何在Android中检查字符串中的行数?

如何检查当前行是不是是sql查询中最后选择的行?

如何根据条件更改 DataGridView 的行颜色以检查日期是不是过期