如何通过单击 QPushButton 打印 QTableWidget
Posted
技术标签:
【中文标题】如何通过单击 QPushButton 打印 QTableWidget【英文标题】:How can I print a QTableWidget by clicking on QPushButton 【发布时间】:2020-08-12 12:16:01 【问题描述】:我有一个带有两个选项卡的界面:在第一个选项卡中,我要求用户输入参数,在第二个选项卡中,我想打印以下 QTableWidget。
所以基本上在第一个选项卡上我有一个 QPushButton,我称之为进程,通常,当我按下它时,我想将信息发送到第二个选项卡。
现在我只是尝试用 QTableWidget 和良好的参数显示一个新窗口:
class Parameters(QWidget):
def __init__(self):
super(Parameters, self).__init__()
self.matrixsize = QLineEdit()
bouton = QPushButton("define matrix_size")
bouton.clicked.connect(self.appui_bouton)
self.halfmatrix = QCheckBox()
self.halfmatrix.toggled.connect(self.on_checked)
self.define_matrix_size = QGroupBox('Define Parameters')
layout = QGridLayout()
layout.addWidget(self.matrixsize, 0, 0, 1, 1, )
layout.addWidget(bouton, 0, 1, 1, 1)
layout.addWidget(QLabel('select half size mode'
), 1, 0, 1, 1)
layout.addWidget(self.halfmatrix, 1, 1, 1, 1)
self.define_matrix_size.setLayout(layout)
process = QPushButton('process')
process.clicked.connect(self.process)
self.matrix = QTableWidget()
self.layout = QGridLayout()
self.layout.addWidget(self.define_matrix_size)
self.layout.addWidget(matrix)
self.layout.addWidget(process)
self.setLayout(self.layout)
def matrix_size(self):
if self.matrixsize.text() == "":
return 0
else:
return int(self.matrixsize.text())
def appui_bouton(self):
taille = self.matrixsize()
self.matrix.deleteLater()
if self.halfmatrix.isChecked():
self.on_checked()
else:
self.matrix = QTableWidget()
self.matrix.setColumnCount(taille)
self.matrix.setRowCount(taille)
self.layout.addWidget(self.matrix)
self.update()
self.setLayout(self.layout)
def keyPressEvent(self, qKeyEvent):
print(qKeyEvent.key())
if qKeyEvent.key() == Qt.Key_Return or qKeyEvent.key() == Qt.Key_Enter:
self.appui_bouton()
else:
super().keyPressEvent(qKeyEvent)
def on_checked(self):
taille = self.matrixsize()
if taille == 0:
pass
else:
if self.halfmatrix.isChecked():
size = int(taille / 2)
self.matrix.deleteLater()
self.matrix = QTableWidget()
self.matrix.setColumnCount(size)
self.matrix.setRowCount(size)
self.layout.addWidget(self.matrix, 3, 0, 20, 4)
self.update()
self.setLayout(self.layout)
else:
self.appui_bouton()
def process (self):
layout = QHBoxLayout()
test = self.matrix
test.setLayout(layout)
test.show()
所以为了澄清我所说的:我有一个窗口,您可以在其中获取一些参数 (size,...) ,当您选择这些参数时,假设您采用 matrixsize==5,那么 5x5 表是添加到窗口。此表可以在此填充后由其他参数(我在代码上剪切它们)通过拖放系统进行。 所以现在我有了一个构建表,我希望能够通过单击“进程”按钮打开一个只包含表的新窗口。 所以我不想要一个动态表,我只想要一个保持相同属性的表(例如,如果矩阵启用了 Dragonly,那么新矩阵应该具有相同的属性)。我想保留单元格中包含的所有信息
我希望我足够清楚这是我第一次提问(当然是在多次阅读一些答案之后^^) 感谢您的回答和建议!
【问题讨论】:
你的意思是process
中的表格应该根据矩阵大小来创建行和列吗?
不,我的意思是:在第一个选项卡中,我可以创建一个包含所需行数的表格(我断言它是一个正方形)。我可以用我想要的任何东西来填充它。我想要的是,当我单击“进程”时,会出现一个带有同一张表的新窗口。 (这是我想要跨过的第一步,之后,我希望单击进程创建一个新窗口,该窗口具有相同的表,并基于数据函数进行演变)。我希望我更清楚
第一个答案发错了,我更正了,现在清楚了吗?
嗯,这部分取决于你要对“新”表做什么:它应该是可编辑的吗?编辑后的数据是否应该与原始表动态同步?此外,您的示例不可重现,它缺少您要连接的两个函数(appui_bouton
和 on_checked
),并且没有关于实际应用表大小的任何痕迹。请编辑问题并使其代码可重现,包括设置表格大小所需的所有功能。
通常这样,它回答了你提出的问题@musicamante
【参考方案1】:
您可以创建一个没有父级的新 QTableWidget(这使其成为***窗口),然后显示它:
class Parameters(QWidget):
# ...
def process(self):
rows = self.matrix.rowCount()
columns = self.matrix.columnCount()
self.newTable = QTableWidget(rows, columns)
for row in range(rows):
for column in range(columns):
source = self.matrix.item(row, column)
if source:
self.newTable.setItem(row, column, QTableWidgetItem(source))
self.newTable.show()
请注意,我将新表创建为实例属性。这可以避免垃圾收集,以防它是一个局部变量(导致小部件显示并立即消失),但不幸的是,如果您再次单击进程按钮并且窗口已经存在,它将被删除并用新窗口“覆盖”。如果你想同时拥有更多的进程窗口,你可以将它们添加到一个列表中:
class Parameters(QWidget):
def __init__(self):
super(Parameters, self).__init__()
# ...
self.processTables = []
def process(self):
rows = self.matrix.rowCount()
columns = self.matrix.columnCount()
# note that now "newTable" is *local*
newTable = QTableWidget(rows, columns)
self.processTables.append(newTable)
# ...
关于您的代码的一些建议:
绝对没有必要在每次想要更改其大小时都创建一个新表;只需在现有值上使用setRowCount
和setColumnCount
,如果您不想保留以前的值,请使用clear()
;
不要使用两个功能几乎相同的函数(appui_bouton
和 on_checked
)并相互调用,只使用一个函数来检查这两个方面;
不要不必要地调用update()
:当你改变一个小部件的属性(或添加一个新的小部件到一个布局)update
已经被调用了;虽然这不是一个实际问题(Qt 会自动管理 何时 更新实际发生,避免在不必要时重新绘制),调用它只会给您的代码添加不必要的噪音;
向网格布局添加小部件时要更加小心(我指的是on_checked
上的代码):如果不需要,不要使用rowSpan 和columnSpan;此外,使用高值是完全没有用的,因为该行中没有其他小部件,并且该布局中实际上只有一列;另外,不要再拨打setLayout()
;
如果您需要数值,请使用QSpinBox,而不是 QLineEdit。
更新现有表格的功能可以更容易地重写,您应该将按钮和复选框连接到它:
class Parameters(QWidget):
def __init__(self):
super(Parameters, self).__init__()
self.matrixsize = QSpinBox()
bouton = QPushButton("define matrix_size")
bouton.clicked.connect(self.appui_bouton)
self.halfmatrix = QCheckBox()
self.halfmatrix.toggled.connect(self.appui_bouton)
# ...
def appui_bouton(self):
taille = self.matrixsize.value()
if self.halfmatrix.isChecked():
taille //= 2
if not taille:
return
self.matrix.setColumnCount(taille)
self.matrix.setRowCount(taille)
【讨论】:
非常感谢您的长评论,我今天会试试这个,看看它在我的代码上是如何工作的以上是关于如何通过单击 QPushButton 打印 QTableWidget的主要内容,如果未能解决你的问题,请参考以下文章
PyQt5 (Python):通过 contextmenu 从 qpushbutton 获取值
PySide:如何在 QPushButton 单击槽中获取单击的 QPushButton 对象?