I have a very simple program that opens a DB and loads a tableview.
So:
Layout file called TestLayouts.py
# -*- coding: utf-8 -*-
################################################################################
## Form generated from reading UI file 'basic.ui'
##
## Created by: Qt User Interface Compiler version 5.14.2
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################
from PySide2.QtCore import (QCoreApplication, QMetaObject,
QRect)
from PySide2.QtWidgets import *
class Ui_MainWindow(object) :
def setupUi(self, MainWindow) :
if not MainWindow.objectName() :
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(1034, 803)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.pushButton = QPushButton(self.centralwidget)
self.pushButton.setObjectName(u"pushButton")
self.pushButton.setGeometry(QRect(920, 730, 89, 25))
self.tableView = QTableView(self.centralwidget)
self.tableView.setObjectName(u"tableView")
self.tableView.setGeometry(QRect(10, 20, 1001, 711))
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow) :
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
# retranslateUi
My main file called tests.py
import sys
import webbrowser
from PySide2 import QtWidgets, QtGui
from PySide2.QtCore import QCoreApplication, QSortFilterProxyModel
from PySide2.QtCore import Slot
from PySide2.QtSql import QSqlDatabase, QSqlQueryModel
from PySide2.QtWidgets import QMenu, QAction
from TestLayouts import Ui_MainWindow
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow) :
def __init__(self, parent=None) :
super(MainWindow, self).__init__()
self.setupUi(self)
self.showMaximized()
self.pushButton.clicked.connect(self._basic)
def _basic(self) :
db = QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("data.sqlite")
db.open()
sourceModel = QSqlQueryModel()
sourceModel.setQuery(
"SELECT id,url FROM database",
db)
proxyModel = QSortFilterProxyModel(self)
proxyModel.setSourceModel(sourceModel)
self.tableView.setModel(proxyModel)
self.tableView.setSortingEnabled(True)
@Slot()
def closeEvent(self, event) :
super(MainWindow, self).closeEvent(event)
QCoreApplication.instance().quit()
def contextMenuEvent(self, event) :
self.menu = QMenu(self)
openlinkAction = QAction('Open Link In A Browser', self)
openlinkAction.triggered.connect(lambda : self.openInANewTab(event))
self.menu.addAction(openlinkAction)
self.menu.popup(QtGui.QCursor.pos())
def openInANewTab(self, event) :
self.row = self.tableView.rowAt(event.pos().y())
self.col = self.tableView.columnAt(event.pos().x())
self.cell = self.tableView.item(self.row, self.col)
cellText = self.cell.text()
webbrowser.open(cellText)
if __name__ == "__main__" :
app = QtWidgets.QApplication([])
w = MainWindow()
w.show()
sys.exit(app.exec_())
Once you run the program and click load, the db loads into view. The right click menu is displayed as expected but on clicking I get the error.
RuntimeError: Internal C++ object (PySide2.QtGui.QContextMenuEvent) already deleted.
I have looked at the few threads like this one here which says
If a QObject falls out of scope in Python, it will get deleted. You have to take care of keeping a reference to the object: Store it as an attribute of an object you keep around, e.g. self.window = QMainWindow()
Pass a parent QObject to the object’s constructor, so it gets owned by the parent
I am not sure how this can be achieved. Any help is appreciated.