簡體   English   中英

如何復制一行QtableWidget並插入到它下面的行?

[英]How to copy a row of QtableWidget and insert to the line below it?

我想要一個表格,其中每行在 QtableWidget 的第一個單元格中都有一個按鈕,並且在按下該按鈕時,整行將與前一行的所有條目(包括按鈕和組合框)一起復制。

我試圖復制它們的文本並且它成功了,但它沒有達到目的,因為它再次需要手動將其分配給組合框等。下面的嘗試,只需在每次點擊時插入一個空行。 該行如何與其元素完全重復?

試圖

from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.m_tablewidget = QtWidgets.QTableWidget(0, 3)
        self.m_tablewidget.setHorizontalHeaderLabels(
            ["Col 1", "Col 2", "Col 3"]
        )
        self.m_button = QtWidgets.QPushButton("Add Row", clicked=self.onClicked)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.addWidget(self.m_tablewidget)
        lay.addWidget(self.m_button, alignment=QtCore.Qt.AlignLeft)

    def table_selector(self, tableName):
        variableSelected = []
        for r in range(tableName.rowCount()):
            row_variables = []
            for c in range(tableName.columnCount()):
                widget = tableName.cellWidget(r, c)
                if isinstance(widget, QtWidgets.QComboBox):
                    current_value = widget.currentText()
                    row_variables.append(current_value)
            variableSelected.append(row_variables)
        return variableSelected

    @QtCore.pyqtSlot()
    def addRow(self):

        rc = self.m_tablewidget.rowCount()
        self.m_tablewidget.insertRow(rc)

    @QtCore.pyqtSlot()
    def onClicked(self):
        d = {
            "a": ["x", "y", "z"],
            "b": ["4", "5", "6"],
            "c": ["21", "22", "23"],
        }

        combobox = QtWidgets.QComboBox()
        for k, v in d.items():
            combobox.addItem(k, v)

        item = QtWidgets.QTableWidgetItem()



        copyROw_button = QtWidgets.QPushButton("ADD ROW", clicked=self.addRow)

        rc = self.m_tablewidget.rowCount()
        self.m_tablewidget.insertRow(rc)

        for i, combo in enumerate((copyROw_button, combobox)):
            self.m_tablewidget.setCellWidget(rc, i, combo)




if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    w = MainWindow()
    w.resize(640, 480)
    w.show()

    sys.exit(app.exec_())

在您的情況下,復制行涉及復制小部件。 根據我的經驗,我得出的結論是,您不能復制小部件(Qt 也不允許這樣做),因此您必須復制小部件的更多相關功能(1) ,而不是復制小部件。

第一件事是確定使一行與另一行不同的特征,在您的情況下,我已經確定:

  • QComboBox 顯示的數據
  • QComboBox 的選定索引。
  • 第三列中的文本

具有您的邏輯的其他元素不會更改(例如,您的應用程序不允許修改按鈕的文本)。

由於我們確定了區分行的特征,因此這些參數必須是創建行的函數所采用的參數。

(1) 這點是主觀的

綜上所述,解決方法如下:

from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.m_tablewidget = QtWidgets.QTableWidget(0, 3)
        self.m_tablewidget.setHorizontalHeaderLabels(
            ["Col 1", "Col 2", "Col 3"]
        )
        self.m_button = QtWidgets.QPushButton("Add Row", clicked=self.onClicked)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QVBoxLayout(central_widget)
        lay.addWidget(self.m_tablewidget)
        lay.addWidget(self.m_button, alignment=QtCore.Qt.AlignLeft)

    @QtCore.pyqtSlot()
    def addRow(self):
        button = self.sender()
        if not isinstance(button, QtWidgets.QPushButton):
            return
        p = button.mapTo(self.m_tablewidget.viewport(), QtCore.QPoint())
        ix = self.m_tablewidget.indexAt(p)
        if not ix.isValid() or ix.column() != 0:
            return
        r = ix.row()
        ix_combobox = 0
        text = ""
        combo = self.m_tablewidget.cellWidget(r, 1)
        if isinstance(combo, QtWidgets.QComboBox):
            ix_combobox = combo.currentIndex()
        item = self.m_tablewidget.item(r, 2)
        if item is not None:
            text = item.text()
        self.insert_row(row=r + 1, ix_combobox=ix_combobox, text=text)

    @QtCore.pyqtSlot()
    def onClicked(self):
        self.insert_row()

    def insert_row(self, d=None, ix_combobox=0, text="", row=-1):
        if d is None:
            d = {
                "a": ["x", "y", "z"],
                "b": ["4", "5", "6"],
                "c": ["21", "22", "23"],
            }
        combobox = QtWidgets.QComboBox()
        for k, v in d.items():
            combobox.addItem(k, v)
        combobox.setCurrentIndex(ix_combobox)
        item = QtWidgets.QTableWidgetItem()
        copyROw_button = QtWidgets.QPushButton("ADD ROW", clicked=self.addRow)
        if row == -1:
            row = self.m_tablewidget.rowCount()
        self.m_tablewidget.insertRow(row)
        for i, combo in enumerate((copyROw_button, combobox)):
            self.m_tablewidget.setCellWidget(row, i, combo)
        if text:
            self.m_tablewidget.setItem(row, 2, QtWidgets.QTableWidgetItem(text))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    w = MainWindow()
    w.resize(640, 480)
    w.show()

    sys.exit(app.exec_())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM