Reputation: 451
below is the code i am using: How to create contextmenu to delete row for inside of qtableview python.
It is showing menu even i clicked on Qpushbutton also but i need to show the delete menu on only inside of qtableview. and let me know the way to delete the row of qtableview data. Please let me know the solution.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import uic
import sys
import sqlite3
class UI(QMainWindow):
def __init__(self):
super(UI, self).__init__()
uic.loadUi("tableview.ui", self)
self.show()
self.view_msa()
self.pushButton.clicked.connect(self.view_msa)
def view_msa(self):
self.model = QtGui.QStandardItemModel(self)
self.tableView.setModel(self.model)
conn = sqlite3.connect('book.db')
cur = conn.cursor()
cur.execute("SELECT * FROM card")
db_data = cur.fetchall()
print(db_data)
for line in db_data:
row = []
for item in line:
cell = QStandardItem(str(item))
row.append(cell)
self.model.setHorizontalHeaderLabels(["Name","Age","Gender"])
self.model.appendRow(row)
def contextMenuEvent(self, event):
self.click_menu = QtWidgets.QMenu()
renameAction = QtWidgets.QAction('Delete', self)
renameAction.triggered.connect(lambda: self.renameSlot(event))
self.click_menu.addAction(renameAction)
self.click_menu.popup(QtGui.QCursor.pos())
def renameSlot(self, event):
print("Renameing slot called")
app = QApplication(sys.argv)
window = UI()
app.exec_()
Upvotes: 1
Views: 627
Reputation: 48489
All widget have the contextMenuPolicy
property, which if set to QtCore.Qt.CustomContextMenu
allows to connect to the customContextMenuRequested(pos)
signal (note that the pos
is in widget coordinates). From there you can access the index that is at the mouse position through indexAt
or, better, get the selectedIndexes (which is useful if you have multiple selection enabled).
class UI(QMainWindow):
def __init__(self):
super(UI, self).__init__()
# ...
self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.tableView.customContextMenuRequested.connect(self.tableMenu)
def tableMenu(self, pos):
selected = self.tableView.selectedIndexes()
if not selected:
return
menu = QtWidgets.QMenu()
deleteAction = menu.addAction('Delete rows')
deleteAction.triggered.connect(lambda: self.removeRows(selected))
menu.exec_(QtGui.QCursor.pos())
def removeRows(self, indexes):
# get unique row numbers
rows = set(index.row() for index in indexes)
# remove rows in *REVERSE* order!
for row in sorted(rows, reverse=True):
self.model.removeRow(row)
Note that in this case you have to use menu.exec()
(which is usually the preferred method), not popup()
, otherwise the function will return instantly and the menu won't probably shown up because of internal processing of the mouse events: exec
blocks until it returns (whether any of its actions are triggered or it's closed), popup
returns immediately.
Upvotes: 2