python - 选择在带有 ComboBox 的 QTableWidget 中不起作用 - 复制事件未触发
问题描述
QTableWidget(PyQt5)中的嵌入式组合框似乎阻止了选择和事件(例如复制)触发。选择和复制事件在没有组合框的情况下工作正常。
我正在使用 eventFilters 来捕获复制事件 (CTRL+C)。如果没有组合框,一切都会按预期工作。您可以选择任何范围的单元格,它可以完美地复制/粘贴到 Excel。
添加组合框后,包含组合框的选择似乎不再触发事件。事实上,当它包含组合框时,选择会从蓝色变为灰色。
有趣的是,当您选择整个表格或整行时,它会保持蓝色,我可以复制和粘贴包括组合框在内的所有内容。不包含组合框的选择也可以正常工作。
下面是带有复制事件过滤器的 QTableWidget 的最小工作示例。
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(528, 436)
self.tableWidget = QtWidgets.QTableWidget(Dialog)
self.tableWidget.setGeometry(QtCore.QRect(0, 0, 523, 399))
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(3)
class dialogForm(QDialog):
def __init__(self, ui_layout):
QDialog.__init__(self)
self.ui = ui_layout
ui_layout.setupUi(self)
self.cbItems = ["A", "B", "C", "D"]
self.setupComboBoxAll()
self.ui.tableWidget.installEventFilter(self)
def setupComboBox(self, row):
comboBoxAircraftName = QComboBox()
comboBoxAircraftName.setProperty("row", row)
comboBoxAircraftName.setProperty("col", 1)
for t in self.cbItems:
comboBoxAircraftName.addItem(t)
self.ui.tableWidget.setCellWidget(row,1,comboBoxAircraftName)
def setupComboBoxAll(self):
for i in range(0, self.ui.tableWidget.rowCount()):
self.setupComboBox(i)
###########################
### NOT BEING TRIGGERED
###########################
# Used for copying and pasting
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.KeyPress and
event.matches(QtGui.QKeySequence.Copy)):
self.copySelection()
return True
return super(dialogForm, self).eventFilter(source, event)
# Allow copying from QTableWidget and Pasting into Excel
def copySelection(self):
selection = self.ui.tableWidget.selectedIndexes()
if selection:
rows = sorted(index.row() for index in selection)
columns = sorted(index.column() for index in selection)
rowcount = rows[-1] - rows[0] + 1
colcount = columns[-1] - columns[0] + 1
table = [[''] * colcount for _ in range(rowcount)]
for index in selection:
row = index.row() - rows[0]
column = index.column() - columns[0]
if column == 1:
table[row][column] = self.ui.tableWidget.cellWidget(row, column).currentText()
else:
table[row][column] = index.data()
stream = io.StringIO()
csv.writer(stream, delimiter='\t').writerows(table)
QtWidgets.qApp.clipboard().setText(stream.getvalue())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = dialogForm(Ui_Dialog())
window.show()
sys.exit(app.exec_())
main()
我正在使用 Windows 10。Anaconda Python 3.6.3
解决方案
解决方案很简单,将过滤器也安装在QComboBox
如下所示的位置:
def setupComboBox(self, row):
comboBoxAircraftName = QComboBox()
comboBoxAircraftName.setProperty("row", row)
comboBoxAircraftName.setProperty("col", 1)
comboBoxAircraftName.installEventFilter(self)
comboBoxAircraftName.addItems(self.cbItems)
self.ui.tableWidget.setCellWidget(row, 1 ,comboBoxAircraftName)
另一个更简单的解决方案是使用QShortcut
:
class dialogForm(QDialog):
def __init__(self, ui_layout):
QDialog.__init__(self)
self.ui = ui_layout
ui_layout.setupUi(self)
self.cbItems = ["A", "B", "C", "D"]
self.setupComboBoxAll()
shorcut = QtWidgets.QShortcut(QtGui.QKeySequence.Copy, self.ui.tableWidget)
shorcut.activated.connect(self.copySelection)
def setupComboBox(self, row):
comboBoxAircraftName = QComboBox()
comboBoxAircraftName.setProperty("row", row)
comboBoxAircraftName.setProperty("col", 1)
comboBoxAircraftName.addItems(self.cbItems)
self.ui.tableWidget.setCellWidget(row, 1 ,comboBoxAircraftName)
def setupComboBoxAll(self):
for i in range(self.ui.tableWidget.rowCount()):
self.setupComboBox(i)
# Allow copying from QTableWidget and Pasting into Excel
def copySelection(self):
selection = self.ui.tableWidget.selectedIndexes()
if selection:
rows = sorted(index.row() for index in selection)
columns = sorted(index.column() for index in selection)
rowcount = rows[-1] - rows[0] + 1
colcount = columns[-1] - columns[0] + 1
table = [[''] * colcount for _ in range(rowcount)]
for index in selection:
row = index.row() - rows[0]
column = index.column() - columns[0]
if column == 1:
table[row][column] = self.ui.tableWidget.cellWidget(row, column).currentText()
else:
table[row][column] = index.data()
stream = io.StringIO()
csv.writer(stream, delimiter='\t').writerows(table)
QtWidgets.qApp.clipboard().setText(stream.getvalue())
推荐阅读
- r - 循环列以标准化那些是数字的
- polynomials - 对 NP 完整性和硬度进行分类
- julia - 如何在Julia中计算两条线之间的距离(2坐标点的序列)
- c# - NET Core Visual Studio 数据库设计器添加属性和 OleDB 引用
- java - 指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。还没有修好
- r - R:创建一个对不同行进行操作并使用其值创建一个新列的函数
- python - 为什么我的代码返回两个结果而不是一个
- python-3.x - 如何在函数中从我的 EDA/stats 管道打印?
- java - 将表单数据发布到服务器(Android)
- php - 谷歌分析没有列出所有网络资源