我想要一个表格,其中每行在 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_())
关于python - 如何复制QtableWidget的一行并插入到它下面的行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56763446/