兄弟或兄弟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中的隐藏列中检索值?的主要内容,如果未能解决你的问题,请参考以下文章