0

I have a QTableWidget and QListWidget that I want to subclass with similar override methods like mousePressEvent(). In an effort to keep my code dry, I would prefer not to have two unique subclasses that have duplicate logic. Can anyone suggest a pattern to use in this case?

Pseudo code:

from PySide2 import QtWidgets, QtCore

class ChildClass(QtWidgets.QListWidget): # Could be QTableWidget
    _main_window = None
    _context_menu = None

    def __init__(self, main_window):
        super().__init__(main_window)
        self._main_window = main_window
        self.setDragEnabled(True)
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.show_context_menu)

    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        self._main_window.set_active_browser(self.parent())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • Can you provide an example of the code you would *like* to be able to write? My guess is that you're looking for a class template but it's difficult to say without seeing some code. Do your derived classes declare their own signals/properties etc.? – G.M. Aug 01 '21 at 20:29
  • @G.M. Yes, the derived classes might declare their own signals. I may also want to extend the derived classes as well. Initially, I thought I could just have an abstract base class and swap that out later for either QtableWidget or QListWidget. I know that it is considered bad form to change objects at runtime like that. – Neil Berard Aug 01 '21 at 21:08

1 Answers1

1

You can use a mixin:

class MousePressOverride:
    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        self._main_window.set_active_browser(self.parent())


class ChildClass(MousePressOverride, QtWidgets.QListWidget):
    # ...

Note that the order of the multiple inheritance is very important, as the mousePressEvent of MousePressOverride has to override that of the QListWidget.

Please consider that if you want to interact/communicate with a parent object, you should consider using signals instead, as that would better comply with the OOP pattern:

class MousePressOverride:
    someSignal = QtCore.pyqtSignal(object)
    def mousePressEvent(self, event):
        super().mousePressEvent(event)
        self.someSignal.emit(self)


class ChildClass(MousePressOverride, QtWidgets.QListWidget):
    def __init__(self):
        super().__init__()
        # ...


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        # ...
        self.view = ChildClass()
        self.view.someSignal.connect(self.set_active_browser)

    def set_active_browser(self, obj):
        # ...
musicamante
  • 41,230
  • 6
  • 33
  • 58