是否可以在pyqt5 qtableWidget对象中检索细胞的含量并将其注入其他单元格?
我想修改一个QTableWidget表,取整行并将其移动代替其他行(以某种方式逆转行的位置)。我进行的所有尝试都无法使用。我在下面举一个最小的例子,以说明我想做什么。这个想法是将每个单元格的内容在行中取出,并将其注入另一行。 此示例
Segmentation fault (core dumped)
中
import sys
from PyQt5.QtWidgets import *
from functools import partial
#Main Window
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 - QTableWidget'
self.left = 0
self.top = 0
self.width = 300
self.height = 170
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.createTable()
self.layout = QVBoxLayout()
self.layout.addWidget(self.tableWidget)
self.setLayout(self.layout)
#Show window
self.show()
#Create table
def createTable(self):
self.tableWidget = QTableWidget()
#Row count
self.tableWidget.setRowCount(3)
#Column count
self.tableWidget.setColumnCount(2)
#cell 0 - 0
self.tableWidget.setItem(0,0, QTableWidgetItem("0 - 0"))
#cell 0 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("0 - 1")
brick_name_button.clicked.connect(partial(self.print_mssg, "0 - 1"))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(0, 1, widget)
#cell 1 - 0
self.tableWidget.setItem(1, 0, QTableWidgetItem("1 - 0"))
#cell 1 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("1 - 1")
brick_name_button.clicked.connect(partial(self.print_mssg, "1 - 1"))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(1, 1, widget)
#cell 2 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("Invert raw 0 and 1")
brick_name_button.clicked.connect(self.invert)
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(2, 1, widget)
#Table will fit the screen horizontally
self.tableWidget.horizontalHeader().setStretchLastSection(True)
self.tableWidget.horizontalHeader().setSectionResizeMode(
QHeaderView.Stretch)
def print_mssg(self, mssg):
print('\n' + mssg + '\n')
def invert(self):
widget_to_move_0 = self.tableWidget.cellWidget(0, 1)
item_to_move_0 = self.tableWidget.takeItem(0, 0)
widget_to_move_1 = self.tableWidget.cellWidget(1, 1)
item_to_move_1 = self.tableWidget.takeItem(1, 0)
self.tableWidget.setCellWidget(1, 1, widget_to_move_0)
self.tableWidget.setItem(1, 0, item_to_move_0)
self.tableWidget.setCellWidget(0, 1, widget_to_move_1)
self.tableWidget.setItem(0, 0, item_to_move_1)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
在 这个问题似乎实际上与Qwidget/Qpushbutton对象有关,因为如果我们仅更改qtableWidgetItem对象,它可以正常工作... 例如,通过上面的Snipet代码,仅使用CellWidget()和SetCellWidget()来评论台词,它可以很好地工作
def invert(self):
#widget_to_move_0 = self.tableWidget.cellWidget(0, 1)
item_to_move_0 = self.tableWidget.takeItem(0, 0)
#widget_to_move_1 = self.tableWidget.cellWidget(1, 1)
item_to_move_1 = self.tableWidget.takeItem(1, 0)
#self.tableWidget.setCellWidget(1, 1, widget_to_move_0)
self.tableWidget.setItem(1, 0, item_to_move_0)
#self.tableWidget.setCellWidget(0, 1, widget_to_move_1)
self.tableWidget.setItem(0, 0, item_to_move_1)
#self.show()
! 实际上,似乎它起作用(我不知道的原因),只有当我们创建一个新的窗口对象(并且不使用单元格中的先前的窗口小组对象)。实际上,下面的小型代码(仅供说明)完美效果:
import sys
from PyQt5.QtWidgets import *
from functools import partial
#Main Window
class App(QWidget):
STATE = True
def __init__(self):
super().__init__()
self.title = 'PyQt5 - QTableWidget'
self.left = 0
self.top = 0
self.width = 300
self.height = 170
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.createTable()
self.layout = QVBoxLayout()
self.layout.addWidget(self.tableWidget)
self.setLayout(self.layout)
#Show window
self.show()
#Create table
def createTable(self):
self.tableWidget = QTableWidget()
#Row count
self.tableWidget.setRowCount(3)
#Column count
self.tableWidget.setColumnCount(2)
#cell 0 - 0
self.tableWidget.setItem(0, 0, QTableWidgetItem("0 - 0"))
#cell 0 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("0 - 1")
brick_name_button.clicked.connect(partial(self.print_mssg, "0 - 1"))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(0, 1, widget)
#cell 1 - 0
self.tableWidget.setItem(1, 0, QTableWidgetItem("1 - 0"))
#cell 1 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("1 - 1")
brick_name_button.clicked.connect(partial(self.print_mssg, "1 - 1"))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(1, 1, widget)
#cell 2 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("Invert raw 0 and 1")
brick_name_button.clicked.connect(self.invert)
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(2, 1, widget)
#Table will fit the screen horizontally
self.tableWidget.horizontalHeader().setStretchLastSection(True)
self.tableWidget.horizontalHeader().setSectionResizeMode(
QHeaderView.Stretch)
def print_mssg(self, mssg):
print('\n' + mssg + '\n')
def invert(self):
item_to_move_0 = self.tableWidget.takeItem(0, 0)
item_to_move_1 = self.tableWidget.takeItem(1, 0)
#change raw 1
widget = QWidget()
layout = QVBoxLayout()
if self.STATE is True:
push_button_name = "0 - 1"
else:
push_button_name = "1 - 1"
brick_name_button = QPushButton(push_button_name)
brick_name_button.clicked.connect(partial(self.print_mssg, push_button_name))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(1, 1, widget)
self.tableWidget.setItem(1, 0, item_to_move_0)
#change raw 0
widget = QWidget()
layout = QVBoxLayout()
if self.STATE is True:
push_button_name = "1 - 1"
else:
push_button_name = "0 - 1"
brick_name_button = QPushButton(push_button_name)
brick_name_button.clicked.connect(partial(self.print_mssg, push_button_name))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(0, 1, widget)
self.tableWidget.setItem(0, 0, item_to_move_1)
self.STATE = not self.STATE
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
I would like to modify a QTableWidget table, taking whole rows and moving them in place of other rows (reversing the position of the rows, in a way). All the attempts I made did not work. I give a minimal example, below, to illustrate what I want to do. The idea is to take the contents of each cell in the row and inject it into another row. In this example the interpreter crashes with the message:
Segmentation fault (core dumped)
Here is the minimum example code:
import sys
from PyQt5.QtWidgets import *
from functools import partial
#Main Window
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 - QTableWidget'
self.left = 0
self.top = 0
self.width = 300
self.height = 170
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.createTable()
self.layout = QVBoxLayout()
self.layout.addWidget(self.tableWidget)
self.setLayout(self.layout)
#Show window
self.show()
#Create table
def createTable(self):
self.tableWidget = QTableWidget()
#Row count
self.tableWidget.setRowCount(3)
#Column count
self.tableWidget.setColumnCount(2)
#cell 0 - 0
self.tableWidget.setItem(0,0, QTableWidgetItem("0 - 0"))
#cell 0 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("0 - 1")
brick_name_button.clicked.connect(partial(self.print_mssg, "0 - 1"))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(0, 1, widget)
#cell 1 - 0
self.tableWidget.setItem(1, 0, QTableWidgetItem("1 - 0"))
#cell 1 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("1 - 1")
brick_name_button.clicked.connect(partial(self.print_mssg, "1 - 1"))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(1, 1, widget)
#cell 2 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("Invert raw 0 and 1")
brick_name_button.clicked.connect(self.invert)
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(2, 1, widget)
#Table will fit the screen horizontally
self.tableWidget.horizontalHeader().setStretchLastSection(True)
self.tableWidget.horizontalHeader().setSectionResizeMode(
QHeaderView.Stretch)
def print_mssg(self, mssg):
print('\n' + mssg + '\n')
def invert(self):
widget_to_move_0 = self.tableWidget.cellWidget(0, 1)
item_to_move_0 = self.tableWidget.takeItem(0, 0)
widget_to_move_1 = self.tableWidget.cellWidget(1, 1)
item_to_move_1 = self.tableWidget.takeItem(1, 0)
self.tableWidget.setCellWidget(1, 1, widget_to_move_0)
self.tableWidget.setItem(1, 0, item_to_move_0)
self.tableWidget.setCellWidget(0, 1, widget_to_move_1)
self.tableWidget.setItem(0, 0, item_to_move_1)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
EDIT1:
The issue seems to be really just related to the QWidget/QPushButton objects because it works fine if we only change the QTableWidgetItem objects ...
For example by taking the snipet code above and only commenting the lines with cellWidget() and setCellWidget(), in the invert method, it works fine!:
def invert(self):
#widget_to_move_0 = self.tableWidget.cellWidget(0, 1)
item_to_move_0 = self.tableWidget.takeItem(0, 0)
#widget_to_move_1 = self.tableWidget.cellWidget(1, 1)
item_to_move_1 = self.tableWidget.takeItem(1, 0)
#self.tableWidget.setCellWidget(1, 1, widget_to_move_0)
self.tableWidget.setItem(1, 0, item_to_move_0)
#self.tableWidget.setCellWidget(0, 1, widget_to_move_1)
self.tableWidget.setItem(0, 0, item_to_move_1)
#self.show()
EDIT2:
In fact it seems that it works (for a reason I don't know), only if we create a new widget object (and not using the previous widget object in the cell). Indeed, the small code, just to illustrate, below works perfectly:
import sys
from PyQt5.QtWidgets import *
from functools import partial
#Main Window
class App(QWidget):
STATE = True
def __init__(self):
super().__init__()
self.title = 'PyQt5 - QTableWidget'
self.left = 0
self.top = 0
self.width = 300
self.height = 170
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.createTable()
self.layout = QVBoxLayout()
self.layout.addWidget(self.tableWidget)
self.setLayout(self.layout)
#Show window
self.show()
#Create table
def createTable(self):
self.tableWidget = QTableWidget()
#Row count
self.tableWidget.setRowCount(3)
#Column count
self.tableWidget.setColumnCount(2)
#cell 0 - 0
self.tableWidget.setItem(0, 0, QTableWidgetItem("0 - 0"))
#cell 0 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("0 - 1")
brick_name_button.clicked.connect(partial(self.print_mssg, "0 - 1"))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(0, 1, widget)
#cell 1 - 0
self.tableWidget.setItem(1, 0, QTableWidgetItem("1 - 0"))
#cell 1 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("1 - 1")
brick_name_button.clicked.connect(partial(self.print_mssg, "1 - 1"))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(1, 1, widget)
#cell 2 - 1
widget = QWidget()
layout = QVBoxLayout()
brick_name_button = QPushButton("Invert raw 0 and 1")
brick_name_button.clicked.connect(self.invert)
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(2, 1, widget)
#Table will fit the screen horizontally
self.tableWidget.horizontalHeader().setStretchLastSection(True)
self.tableWidget.horizontalHeader().setSectionResizeMode(
QHeaderView.Stretch)
def print_mssg(self, mssg):
print('\n' + mssg + '\n')
def invert(self):
item_to_move_0 = self.tableWidget.takeItem(0, 0)
item_to_move_1 = self.tableWidget.takeItem(1, 0)
#change raw 1
widget = QWidget()
layout = QVBoxLayout()
if self.STATE is True:
push_button_name = "0 - 1"
else:
push_button_name = "1 - 1"
brick_name_button = QPushButton(push_button_name)
brick_name_button.clicked.connect(partial(self.print_mssg, push_button_name))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(1, 1, widget)
self.tableWidget.setItem(1, 0, item_to_move_0)
#change raw 0
widget = QWidget()
layout = QVBoxLayout()
if self.STATE is True:
push_button_name = "1 - 1"
else:
push_button_name = "0 - 1"
brick_name_button = QPushButton(push_button_name)
brick_name_button.clicked.connect(partial(self.print_mssg, push_button_name))
layout.addWidget(brick_name_button)
widget.setLayout(layout)
self.tableWidget.setCellWidget(0, 1, widget)
self.tableWidget.setItem(0, 0, item_to_move_1)
self.STATE = not self.STATE
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
看来这是不可能的。
必须创建一个新的小部件对象,当使用 setCellwidget()方法。
因此,对于问题中示例中的一小部分代码,解决方案将如下:
It seems that this is not possible.
A new widget object must be created, the old one will be destroyed when using the setCellWidget() method.
So, for the small piece of code in the example in the question, a solution would be as follows: