如何在PyQt5中捕捉QTableWidget的左右鼠标点击事件?
How to catch left and right mouse click event on QTableWidget in PyQt5?
我使用 PyQt5
和 openpyxl
创建了一个 QTableWidget
以在 VSCode 中加载 excel 和我无法分别 catch/get 鼠标左键和右键单击按钮。左键单击可将单元格内容复制到剪贴板,右键单击单元格可粘贴剪贴板中的内容。
基本上,左键单击复制单元格 -> 保存到剪贴板 -> 右键单击粘贴到单元格。
应用程序的逐步过程:
1 - 左键单击这些单元格中的任何一个将复制内容
2 - 复制的内容将在剪贴板区域 saved/pasted 此处 (QLineEdit/QLabel
)
3 - 右键单击这些单元格中的任何一个将粘贴剪贴板中的内容
4 - 在矩形中显示 QTableWidget 的区域
这些是我试过但没有用的一些代码:
# def tablewidget_clicked(self):
# self.mclick = self.tableWidget.mousePressEvent
# print(str(self.mclick))
# self.leftclick = QtCore.Qt.LeftButton
# print(str(self.leftclick)) # Displays 1
# self.rightclick = QtCore.Qt.RightButton
# print(str(self.rightclick)) # Displays 2
# self.midclick = QtCore.Qt.MiddleButton
# print(str(self.midclick)) # Displays
# if QtGui.QMouseEvent.button(QtCore.Qt.MouseButton): #== QtCore.Qt.LeftButton:
# print('hello')
# else:
# print('hi')
def eventFilter(self, source, event):
if event.type() == QtGui.QMouseEvent.MouseButtonPress:
if event.button() == QtCore.Qt.LeftButton:
print('hello')
return True
else:
return False
甚至为 self.tableWidget
创建视口也没有用。
self.tablevport = self.tableWidget.viewport()
self.tablevport.installEventFilter(self)
self.tablevport.mousePressEvent()
到目前为止,下面 的这些代码有效(作为测试),但同时读取左键和右键单击。
self.tableWidget.cellClicked.connect(self.tablewidget_clicked)
def tablewidget_click(self):
if QtCore.Qt.LeftButton:
print('hello')
if QtCore.Qt.RightButton:
print('hi')
如果我能在这个应用程序中获得一个代码模式来实现我的目标,那将对我有很大帮助。我在搜索 google 和 youtube 时运气不佳。
最后,我相信或者至少我认为我在这里有很多缺陷,比如编码风格,将 QTableWidget 与其他 class 分开,很长的代码,也许我可以从其他 .py 文件导入。但我仍在学习并以某种方式一点一点地改进。我确实希望我的问题的这种表述可以很容易理解。
使用 cellClicked
信号是不够的,因为它只对鼠标左键有效。另外,你的函数实际上并没有检查任何东西,因为 Qt.LeftButton
和 Qt.RightButton
都是常量,你实际上是在做这样的事情:
def tablewidget_click(self):
if 1:
print('hello')
if 2:
print('hi')
使用事件过滤器是正确的选择,但我不明白你为什么要调用 self.mousePressEvent()
:QMouseEvent 应该作为参数,你通常应该 而不是 手动调用事件处理程序。此外,调用 self.tableWidget.viewport()
不会“创建”一个视口,它只是 returns 它,因为所有基于滚动区域的小部件都有一个。
这是一个工作示例:
class Test(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.clipboardLabel = QtWidgets.QLabel()
layout.addWidget(self.clipboardLabel)
self.tableWidget = QtWidgets.QTableWidget(10, 10)
layout.addWidget(self.tableWidget)
self.tableWidget.viewport().installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.MouseButtonPress:
if event.button() == QtCore.Qt.LeftButton:
index = self.tableWidget.indexAt(event.pos())
if index.data():
self.clipboardLabel.setText(index.data())
elif event.button() == QtCore.Qt.RightButton:
index = self.tableWidget.indexAt(event.pos())
if index.isValid():
item = self.tableWidget.itemFromIndex(index)
if not item:
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setItem(index.row(), index.column(), item)
item.setText(self.clipboardLabel.text())
return super().eventFilter(source, event)
我使用 PyQt5
和 openpyxl
创建了一个 QTableWidget
以在 VSCode 中加载 excel 和我无法分别 catch/get 鼠标左键和右键单击按钮。左键单击可将单元格内容复制到剪贴板,右键单击单元格可粘贴剪贴板中的内容。
基本上,左键单击复制单元格 -> 保存到剪贴板 -> 右键单击粘贴到单元格。
应用程序的逐步过程:
1 - 左键单击这些单元格中的任何一个将复制内容
2 - 复制的内容将在剪贴板区域 saved/pasted 此处 (QLineEdit/QLabel
)
3 - 右键单击这些单元格中的任何一个将粘贴剪贴板中的内容
4 - 在矩形中显示 QTableWidget 的区域
这些是我试过但没有用的一些代码:
# def tablewidget_clicked(self):
# self.mclick = self.tableWidget.mousePressEvent
# print(str(self.mclick))
# self.leftclick = QtCore.Qt.LeftButton
# print(str(self.leftclick)) # Displays 1
# self.rightclick = QtCore.Qt.RightButton
# print(str(self.rightclick)) # Displays 2
# self.midclick = QtCore.Qt.MiddleButton
# print(str(self.midclick)) # Displays
# if QtGui.QMouseEvent.button(QtCore.Qt.MouseButton): #== QtCore.Qt.LeftButton:
# print('hello')
# else:
# print('hi')
def eventFilter(self, source, event):
if event.type() == QtGui.QMouseEvent.MouseButtonPress:
if event.button() == QtCore.Qt.LeftButton:
print('hello')
return True
else:
return False
甚至为 self.tableWidget
创建视口也没有用。
self.tablevport = self.tableWidget.viewport()
self.tablevport.installEventFilter(self)
self.tablevport.mousePressEvent()
到目前为止,下面 的这些代码有效(作为测试),但同时读取左键和右键单击。
self.tableWidget.cellClicked.connect(self.tablewidget_clicked)
def tablewidget_click(self):
if QtCore.Qt.LeftButton:
print('hello')
if QtCore.Qt.RightButton:
print('hi')
如果我能在这个应用程序中获得一个代码模式来实现我的目标,那将对我有很大帮助。我在搜索 google 和 youtube 时运气不佳。
最后,我相信或者至少我认为我在这里有很多缺陷,比如编码风格,将 QTableWidget 与其他 class 分开,很长的代码,也许我可以从其他 .py 文件导入。但我仍在学习并以某种方式一点一点地改进。我确实希望我的问题的这种表述可以很容易理解。
使用 cellClicked
信号是不够的,因为它只对鼠标左键有效。另外,你的函数实际上并没有检查任何东西,因为 Qt.LeftButton
和 Qt.RightButton
都是常量,你实际上是在做这样的事情:
def tablewidget_click(self):
if 1:
print('hello')
if 2:
print('hi')
使用事件过滤器是正确的选择,但我不明白你为什么要调用 self.mousePressEvent()
:QMouseEvent 应该作为参数,你通常应该 而不是 手动调用事件处理程序。此外,调用 self.tableWidget.viewport()
不会“创建”一个视口,它只是 returns 它,因为所有基于滚动区域的小部件都有一个。
这是一个工作示例:
class Test(QtWidgets.QWidget):
def __init__(self):
super().__init__()
layout = QtWidgets.QVBoxLayout(self)
self.clipboardLabel = QtWidgets.QLabel()
layout.addWidget(self.clipboardLabel)
self.tableWidget = QtWidgets.QTableWidget(10, 10)
layout.addWidget(self.tableWidget)
self.tableWidget.viewport().installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.MouseButtonPress:
if event.button() == QtCore.Qt.LeftButton:
index = self.tableWidget.indexAt(event.pos())
if index.data():
self.clipboardLabel.setText(index.data())
elif event.button() == QtCore.Qt.RightButton:
index = self.tableWidget.indexAt(event.pos())
if index.isValid():
item = self.tableWidget.itemFromIndex(index)
if not item:
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setItem(index.row(), index.column(), item)
item.setText(self.clipboardLabel.text())
return super().eventFilter(source, event)