兄弟或兄弟AtRow()函数如何从QTableWidget中的隐藏列中检索值?

Posted

技术标签:

【中文标题】兄弟或兄弟AtRow()函数如何从QTableWidget中的隐藏列中检索值?【英文标题】:How does sibling or siblingAtRow() function works to retrieve the value from hidden Column in QTableWidget? 【发布时间】:2022-01-20 18:49:26 【问题描述】:

我有一个数据库,数据从该数据库进入 QTableWidget。数据库中的表有以下几列,

ID (主键,自增值) 姓名 位置

QTableWidget 有以下列(我已添加)

ID (此列,我已隐藏。它包含数据库表中“ID”列的值) Sr#(代表表的行号) 名称​​(包含数据库表中的“名称”) 位置(包含“来自数据库表的位置) 操作(包含该行的删除按钮)

隐藏,我的意思是说我已经使用以下命令隐藏了这个列,

self.ui.table.setColumnHidden(0, True); 

这就是我填充 QTableWidget 并创建删除函数的方式,

    def get_data(self):
        mycursor = self.DB.cursor()
        Subquery = "select id, name, location "
        Subquery += " from tbl_person"
        mycursor.execute(Subquery)
        numcols = len(mycursor.fetchall()[0])
        mycursor.execute(Subquery)
        numrows = len(mycursor.fetchall())
        self.ui.table.setRowCount(numrows)
        self.ui.table.setColumnCount(numcols+2)
        mycursor.execute(Subquery)
        tablerow = 0
        for row in mycursor.fetchall():
            layout = QHBoxLayout()
            layout.setContentsMargins(0, 0, 0, 0)
            layout.setSpacing(0)
            delete_button = QPushButton("Delete Data")
            delete_button.clicked.connect(self.executeDeleteFunction)
            # delete_button.setStyleSheet(delete_push_button) -> Only for styling
            self.ui.table.setItem(tablerow, 0, PySide2.QtWidgets.QTableWidgetItem(str(row[0])))
            self.ui.table.setItem(tablerow, 1, PySide2.QtWidgets.QTableWidgetItem(str(tablerow+1)))
            self.ui.table.setItem(tablerow, 2, PySide2.QtWidgets.QTableWidgetItem(str(row[1])))
            self.ui.table.setItem(tablerow, 3, PySide2.QtWidgets.QTableWidgetItem(str(row[2])))
            self.ui.table.setCellWidget(tablerow, 4, delete_button)
            tablerow += 1
        self.ui.table.setColumnHidden(0, True)
        #self.ui.registered_table.horizontalHeader().setSectionResizeMode(PySide2.QtWidgets.QHeaderView.Stretch)
        self.ui.table.resizeColumnsToContents()

def executeDeleteFunction(self):
    self.person_id = self.ui.table.selectionModel().selectedIndexes()[0]
    self.person_id = self.person_id.row()
    mycursor = self.DB.cursor()
    sql = "delete from tbl_person where id = %s"
    val = (id, )
    mycursor.execute(sql, val)
    print("Deletion Successful")

在删除函数上,这段代码所做的基本上是从 QTableWidget 中获取 **Sr # ** 列的值并据此删除数据,即它从visible first column 中获取值和不是actual first column。但是,我想要来自 隐藏的 QTableWidget 的“ID”列中的数据

我尝试查找 how to get the value from the first hidden column on the QTableWidget 并最终找到此链接:How to get data from hidden 'id' column in QtableWidget

这显然解决了我的问题,但我似乎无法让它适用于我的代码。我不想检索多行的值,而只想检索一行的值,所以我该怎么做(因为我只删除一行。但在提到的问题中,我相信它正在从多行获取数据每个循环)?

此外,我试图找到有关sibling 功能的帮助(在上述问题的答案中提供)但是我找不到有关此功能的任何好的资源(即如何使用它,或一些实用的示例等)

我用 Sibling 函数尝试了以下方法来获取所选行的第一个隐藏列的值,但它不起作用,

self.value = self.table.selectedItems()[0]
self.value = sibling(self.value.row(), 0)

【问题讨论】:

你的问题有点混乱。首先,您的查询似乎是关于一个实际的 Qt 项目模型,但您的问题和标签是指 QTableWidget,它有自己的(稍微私有和代码构建的)模型。此外,您在谈论隐藏列,但随后您说您获得了多个 ,这使得它更加混乱。如果您正在创建 QTableWidget ignoring 自动增量列,则无法以任何方式获取它,除非您创建对它的引用;实际上,如果您只是创建忽略第一列的表格布局,您将永远将其取回。 所以,我强烈建议您edit 提出您的问题,提供minimal reproducible example 并添加更多clear 详细信息,说明您得到了什么、如何做以及什么你想得到。 @musicamante 我已对问题进行了修改。我的问题与 Qt Item 模型有关(但是,因为我正在研究 QTableWidget,所以这就是我添加它的标签的原因)。我没有得到多行,我只需要来自one selected row 的数据,但是,我链接的问题是从多行获取数据(据我所知)。我希望这个问题现在更容易理解了。 【参考方案1】:

给定的代码存在一些概念问题。

首先,应该首选QtSql模块,而不是人为创建模型。对于基本表,QSqlTableModel 就足够了,而对于自定义查询,QSqlQueryModel 是一个不错的选择。

现在的问题是基于 UI 的选择总是基于可见项:如果您在具有隐藏列的视图中选择一行,您将不会得到属于这些列的隐藏索引。

为了获得表格小部件上隐藏列的索引(如QModelIndex),唯一的方法对于表格视图是相同的:你需要访问 model 并获取行的索引,或者您获取实际的模型索引然后获取兄弟(在概念上与底层函数相同):

    item = self.table.selectedItems()[0]
    index = self.table.indexForItem(index)
    firstRowIndex = index.sibling(index.row(), 0)
    sqlIndex = firstRowIndex.data() # might be a string

注意你也可以使用siblingAtColumn():

    firstRowIndex = index.siblingAtColumn(0)

那是因为当你创建 QTableWidget 项目时,你实际上是在创建一个 new 模型,而 that 模型的行并不反映实际的“行”源模型中的索引;第二行中的项目将为 row() 返回 1,即使它们的实际行不同,这是因为该项目已作为 second 添加到表小部件中,因为它是第二个 item 在查询中。

因此,解决方案是获取第一列索引兄弟的增量行值,或者使用预定义的 Sql 模型之一。

对于简单的模型,后一种解决方案已经足够了,但如果你需要更复杂的模型,第一种肯定更准确可靠。

【讨论】:

好的,你说的我明白了。感谢您提供详细的答案。不幸的是,我现在不可能转换为 QSqlTableModel,因为我已经做了一个相当大的项目,其中有大约 6-7 个 QTableWidgets,它们都需要更改。但是,幸运的是,我的其他列值(组合时)是唯一的,因此,我现在正在使用这些值来检索/更新数据库中的数据(即通过使用名称 + 位置的值,这不是有效的方法,但它是一个好方法解决方法) 我还有一个问题,如果你有空并且可以回答的话。我发现这篇文章与我的一个非常相似的问题:***.com/a/56799063/11454905 根据这篇文章,您实际上可以隐藏/显示第一列并检索其值。你能告诉我这是否可能吗?我尝试做同样的事情但是它没有用(self.ui.table.selectedModel.selectedIndexes()[0] 仍然给了我第二列的ID(即第一个可见列))......或者它可能有效因为他们使用的是 QSqlQueryModel? @TalhaAyub 坦率地说,我发现这个问题令人困惑(OP 隐藏了行,但他们正在谈论列)并且答案可怕且不可靠:显示和隐藏行或列可能会导致所有几何体(标题,项目等)的完整计算,向模型请求大量数据,并重新绘制整个小部件,如果没有为SelectRows它设置选择行为不会更新选择。使用我给你的方法更可靠、更快、更一致。我强烈建议您考虑切换到 QSqlTableModel,因为在某些时候 -> @TalhaAyub 您可能会发现自己的代码过于复杂,因为您必须以编程方式不断更新数据库。出于这个原因,甚至有可能有一天你需要切换,而那一天所需的工作量将会大大增加。 当然,检索所有表的唯一行以及使用 ID 以外的列会变得有点复杂。非常感谢您抽出宝贵的时间,我想我将不得不彻底更换桌子。谢谢!

以上是关于兄弟或兄弟AtRow()函数如何从QTableWidget中的隐藏列中检索值?的主要内容,如果未能解决你的问题,请参考以下文章

用于查找没有兄弟元素的 Xpath

如何从包中的兄弟模块导入?

js或jquery如何获取父级子级兄弟元素(包括祖级孙级等)

来自位于 ngFor 内的兄弟组件的角度切换布尔变量

如何在用户输入中识别名称(从文本文件中识别,然后打印名称)

js jquery获取当前元素的兄弟级 上一个 下一个元素 jquery如何获取第一个或最后一个子元素