pyqt5 - 通过索引访问时,QTableWidget 拖/放行不会更改其位置

标签 pyqt5 qtablewidget qtablewidgetitem

我有一个 QTableWidget,它允许通过拖放移动行。

初始表格如下所示:

enter image description here

如果单击该按钮,它将打印表中的所有值。

现在将第 2 行拖动到第 4 行的位置后,输出不会改变。

enter image description here

输出:

Item in row 0, col 0 has value Name
Item in row 0, col 1 has value City
Item in row 1, col 0 has value Aloysius
Item in row 1, col 1 has value Indore
Item in row 2, col 0 has value Alan
Item in row 2, col 1 has value Bhopal
Item in row 3, col 0 has value Arnavi
Item in row 3, col 1 has value Mandsaur

预期输出:

Item in row 0, col 0 has value Name
Item in row 0, col 1 has value City
Item in row 1, col 0 has value Alan
Item in row 1, col 1 has value Bhopal
Item in row 2, col 0 has value Arnavi
Item in row 2, col 1 has value Mandsaur
Item in row 3, col 0 has value Aloysius
Item in row 3, col 1 has value Indore

为什么会出现这种情况?如何按实际的新位置打印所有行?

示例:

import sys
import PyQt5

from PyQt5.QtCore import *#QPointF, QRectF
from PyQt5.QtGui import *#QPainterPath, QPolygonF, QBrush,QPen,QFont,QColor, QTransform
from PyQt5.QtWidgets import *#QApplication, QGraphicsScene, QGraphicsView, QGraphicsSimpleTextIt


class App(QWidget):
    def __init__(self):
        super().__init__()
        self.title = 'PyQt5 - QTableWidget'
        self.left = 0
        self.top = 0
        self.width = 300
        self.height = 200

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.tableWidget = QTableWidget()
        self.tableWidget.verticalHeader().setSectionsMovable(True)
        self.tableWidget.verticalHeader().setDragEnabled(True)
        self.tableWidget.verticalHeader().setDragDropMode(QAbstractItemView.InternalMove)

        # Row count
        self.tableWidget.setRowCount(4)

        # Column count
        self.tableWidget.setColumnCount(2)

        self.tableWidget.setItem(0, 0, QTableWidgetItem("Name"))
        self.tableWidget.setItem(0, 1, QTableWidgetItem("City"))
        self.tableWidget.setItem(1, 0, QTableWidgetItem("Aloysius"))
        self.tableWidget.setItem(1, 1, QTableWidgetItem("Indore"))
        self.tableWidget.setItem(2, 0, QTableWidgetItem("Alan"))
        self.tableWidget.setItem(2, 1, QTableWidgetItem("Bhopal"))
        self.tableWidget.setItem(3, 0, QTableWidgetItem("Arnavi"))
        self.tableWidget.setItem(3, 1, QTableWidgetItem("Mandsaur"))

        # Table will fit the screen horizontally
        self.tableWidget.horizontalHeader().setStretchLastSection(True)
        self.tableWidget.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.tableWidget)

        self.button = QPushButton("Print all the values in the table, in the right order!")

        def get_all_the_values_in_the_table():
            #row_counter = 0
            print("  ")
            print("  ")
            for row in range(self.tableWidget.rowCount()):

                for col in range(self.tableWidget.columnCount()):
                    print("Item in row "+str(row)+", col "+str(col)+" has value "+str(self.tableWidget.item(row,col).text()))

        self.button.clicked.connect(lambda: get_all_the_values_in_the_table())
        self.layout.addWidget(self.button)

        self.setLayout(self.layout)

        # Show window
        self.show()






if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

编辑1:

认为该项目可能在表中具有相同的位置,但索引不同。然而试图通过获取索引来解决这个问题也不起作用。窍门在哪里?

print("Item in row "+str(row_)+", col "+str(col_)+" has value "+str(self.tableWidget.itemFromIndex(self.tableWidget.indexFromItem(self.tableWidget.item(row_,col_))).text()))

最佳答案

移动标题部分不会改变模型布局,只会改变视觉表示:如果将第一个标题移动到另一个位置,第一模型中的 em> 仍将是前一个。事实上,如果仔细观察垂直标题,标签(默认情况下表示模型索引)也会移动。

如果要根据页眉布局打印模型,需要调用logicalIndex() :

        def get_all_the_values_in_the_table():
            print()
            print()
            header = self.tableWidget.verticalHeader()
            for i in range(self.tableWidget.rowCount()):
                # get the logical index based on the visual index
                row = header.logicalIndex(i)
                for col in range(self.tableWidget.columnCount()):
                    print("Item in row {}, col {} has value {}".format(
                        i, col, self.tableWidget.item(row,col).text()))

        self.button.clicked.connect(get_all_the_values_in_the_table)

请注意:

  • 使用 lambda 调用不需要特定参数的方法或函数是不必要的,只需按照上面的方式连接到函数即可;
  • width()height()是所有 QWidget 的现有成员,您不应覆盖它们;
  • 无需调用 setDragEnabledsetDragDropMode 来使 header 部分可移动,setSectionsMovable 就足够了;

关于pyqt5 - 通过索引访问时,QTableWidget 拖/放行不会更改其位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70268456/

相关文章:

python - PyQt5:QTableWidget 中复选框的状态更改

python - 如何从 QTableWidget 中获取选定的组合框值?

python - 如何从索引列表中选择 QtableWidget 中的单元格

python - 有没有办法同步调用方法 'toHtml' ,它是 QWebEnginePage 的对象?

python - QLabel 在 OpenCV 图像处理后没有更新图像

python - 根据是否选中 QCheckbox 获取表行值

python - 如何在 SQLITE3 上关闭和删除数据库后再次打开数据库

QTableWidget 标题不显示

qt - 如何防止用户调整 QTableWidget 列的大小?

mysql - QTableWidget 有一个包含可检查项目的列,但我无法将复选框的切换提交给 MYSQL db