简体   繁体   English

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

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

I have a QTableWidget, that allows moving of rows by dragging and dropping.我有一个 QTableWidget,它允许通过拖放移动行。

The initial table looks as follows:初始表如下所示:

在此处输入图像描述

If clicking on the button, it prints all the values as they are in the table.如果单击该按钮,它会打印表中的所有值。

Now after dragging row 2 to the the position of row 4, the output does not change.现在将第 2 行拖到第 4 行的 position 后,output 不会改变。

在此处输入图像描述

Output: Output:

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

The expected output:预期的 output:

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

Why is this the case and how can I print all the rows by their actual, new location?为什么会出现这种情况,如何按实际的新位置打印所有行?

Example:例子:

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_())

Edit 1:编辑1:

Thought that perhaps the item has the same location in the table, but a different index.认为也许该项目在表中具有相同的位置,但索引不同。 Yet trying to solve this by getting the index does not work neither.然而,试图通过获取索引来解决这个问题也不起作用。 Where's the trick?诀窍在哪里?

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

Moving header sections does not change the model layout, only the visual representation: if you move the first header to another place, the first row in the model will still be the previous one. Moving header sections does not change the model layout, only the visual representation: if you move the first header to another place, the first row in the model will still be the previous one.

If you want to print the model based on the header layout, you need to call logicalIndex() :如果要基于 header 布局打印 model ,则需要调用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)

Note that:注意:

  • calling a method or function that doesn't require specific lambda arguments is unnecessary, just connect to the function as done above;调用不需要特定 lambda arguments 的方法或 function 是不必要的,只需连接到上面的 ZC1C425268E617A94D
  • width() and height() are existing members of all QWidgets, you should not overwrite them; width()height()是所有 QWidgets 的现有成员,你不应该覆盖它们;
  • it's not necessary to call setDragEnabled and setDragDropMode to make header sections movable, as setSectionsMovable will suffice;不必调用setDragEnabledsetDragDropMode来使 header 部分可移动,因为setSectionsMovable就足够了;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM