代码之家  ›  专栏  ›  技术社区  ›  Kevin_ALA

如何复制一行QtableWidget并插入到它下面的行中?

  •  0
  • Kevin_ALA  · 技术社区  · 5 年前

    我想要一个表格,其中每一行在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_())
    
    1 回复  |  直到 5 年前
        1
  •  2
  •   eyllanesc Yonghwan Shin    5 年前

    相关特征 (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_())