如何在PyQt5中的QTableWidget上捕获左右鼠标单击事件?

时间:2020-09-21 13:03:51

标签: python pyqt5 openpyxl qtablewidget

我已经使用QTableWidgetPyQt5创建了一个openpyxl以便在 VSCode 中加载excel,但是我很难抓住/获得左右鼠标单击单独的按钮。左键单击以将单元格内容复制到剪贴板,右键单击以将单元格内容粘贴到剪贴板。 基本上,左键单击复制单元格->保存到剪贴板->右键单击粘贴到单元格。 enter image description here

应用程序的逐步过程:
1-左键单击任何这些单元格将复制内容
2-复制的内容将保存/粘贴在剪贴板区域(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')

如果我可以在此应用程序中获得代码模式以实现自己的目标,将会对我有很大帮助。我没有通过谷歌和YouTube搜索的运气。
最后,我相信或者至少我认为我在这里有很多缺陷,例如编码风格,将QTableWidget与其他类分开,很长的代码,也许我可以从其他.py文件中导入这些代码。但是我仍在学习,并以某种方式有所改进。我希望我的问题的介绍可以很容易理解。

1 个答案:

答案 0 :(得分:2)

使用cellClicked信号是不够的,因为它仅适用于鼠标左键。另外,您的函数实际上不检查任何内容,因为Qt.LeftButtonQt.RightButton都是常量,实际上您正在执行以下操作:

    def tablewidget_click(self):
        if 1:
            print('hello')
        if 2:
            print('hi')

使用事件过滤器是正确的选择,但我不明白为什么要调用self.mousePressEvent():期望将QMouseEvent作为参数,通常应该 not 调用事件处理程序手动。另外,调用self.tableWidget.viewport()并不会“创建”一个视口,它只是将其返回,因为所有基于滚动区域的小部件都有一个。

这是一个可行的示例:

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)