我想要一个表,其中每行在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_())
答案 0 :(得分:2)
在您的情况下,复制行涉及复制小部件。根据我的经验,我得出的结论是您不能复制小部件(Qt也不允许它),因此必须复制更多相关功能 (1),而不是复制小部件。 的小部件。
第一件事是确定使行与其他行有所不同的特征,在您的情况下,我已经确定:
具有您逻辑的其他元素不会更改(例如,您的应用程序不允许修改按钮的文本)。
由于我们确定了区分行的功能,因此这些参数必须是创建行的函数所采用的参数。
(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_())