QTableWidget Drag/Drop行在按索引访问时不会改变它们的位置

QTableWidget Drag/Drop rows does not change their location when accessing by index

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

初始table如下所示:

如果单击按钮,它会打印 table 中的所有值。

现在将第2行拖到第4行的位置后,输出没有变化。

输出:

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:

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

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

移动header部分不会改变模型布局,只有视觉表示:如果你移动第一个header 到另一个地方,模型中的第一个 仍然是之前的那个。事实上,如果你仔细观察垂直 header,标签(默认表示 模型索引 )也会被移动。

如果要打印基于header布局的模型,需要调用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() and height()是所有QWidgets的现有成员,你不应该覆盖它们;
  • 不需要调用 setDragEnabledsetDragDropMode 来使 header 部分可移动,因为 setSectionsMovable 就足够了;