Reputation: 317
I have created a QTableWidget
using PyQt5
and openpyxl
to load excel in VSCode and I am having trouble to catch/get the left and right mouse click buttons separately. Left click to copy the cell content to the clipboard and Right click to cell to paste the content from the clipboard.
Basically, left click copy cell -> save to clipboard -> right click paste to cell.
Step by step process of the App:
1 - Left clicking any of these cells will copy the content
2 - The content copied will be saved/pasted here on the clipboard area (QLineEdit/QLabel
)
3 - Right clicking on any of these cells will paste the content from the clipboard
4 - Shows the area of the QTableWidget in rectangle
These are some of the codes I tried but didn't work:
# 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
Even creating viewport for self.tableWidget
didn't work.
self.tablevport = self.tableWidget.viewport()
self.tablevport.installEventFilter(self)
self.tablevport.mousePressEvent()
So far these codes below work (as a test), but reads both left and right click at the same time.
self.tableWidget.cellClicked.connect(self.tablewidget_clicked)
def tablewidget_click(self):
if QtCore.Qt.LeftButton:
print('hello')
if QtCore.Qt.RightButton:
print('hi')
It would help me a lot if I could get a code-pattern to achieve my goals here in this app. I had no luck in searching through google and youtube.
Lastly, I believe or at least I think I have so many flaws here like the coding style, separating QTableWidget to other class, pretty long codes which maybe I could have imported from other .py files. But I am still learning and somehow improving bit by bit. I do hope this presentation of my problem can be easily understood.
Upvotes: 2
Views: 10934
Reputation: 48509
Using the cellClicked
signal won't be enough, because it only works for the left mouse button. Also, your function doesn't actually check anything, as both Qt.LeftButton
and Qt.RightButton
are constants and you were practically doing something like this:
def tablewidget_click(self):
if 1:
print('hello')
if 2:
print('hi')
Using an event filter was the right choice, but I don't understand why you would call self.mousePressEvent()
: a QMouseEvent is expected as argument, and you should normally not call event handlers manually. Also, calling self.tableWidget.viewport()
does not "create" a viewport, it just returns it, as all scroll area based widgets have one.
Here's a working example:
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)
Upvotes: 5