Python Forum
Python C++ Template Equivalent
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python C++ Template Equivalent
#1
I have the following code that adds a couple of features to QWidget and QGroupBox.
class View(QtWidgets.QWidget):
    """Add upload and update loop to QWidget"""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.update_list = UpdateList(1.0)

    def showEvent(self, event):
        """Start update loop when window is shown"""
        self.upload()
        self.update_list.start()
        event.accept()

    def closeEvent(self, event):
        """Stop update loop when window is closed"""
        self.update_list.stop()
        event.accept()

    def upload(self):
        """Forward update message to all ValueControl objects"""
        if self.isVisible():
            for child in self.children():
                if isinstance(child, ValueControl):
                    child.update_value()


class GroupView(QtWidgets.QGroupBox):
    """Add upload and update loop to QBoxGroup"""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.update_list = UpdateList(1.0)

    def showEvent(self, event):
        """Start update loop when window is shown"""
        self.upload()
        self.update_list.start()
        event.accept()

    def closeEvent(self, event):
        """Stop update loop when window is closed"""
        self.update_list.stop()
        event.accept()

    def upload(self):
        """Forward update message to all ValueControl objects"""
        if self.isVisible():
            for child in self.children():
                if isinstance(child, ValueControl):
                    child.update_value()
The code is identical except for the superclass. I would like to make a superclass that implements the common behavior, but openEvent(), closeEvent() and self.children() are all part of the new behavior and these methods are inherited from QWidget.

In C++ I would make a template. How would you do this in Python?
Reply
#2
You could perhaps write a Mixin class implementing the three methods.
Reply
#3
I tried a mixin. It works, but the mixin provides only half the additional functionality because it really needs to act like a QWidget to get the show/close events.
class BaseView():
    """Abstract base class for views"""
    def __init__(self):
       self.update_list = UpdateList(1.0)

    def upload(self):
        """Forward update message to all ValueControl objects"""
        if self.isVisible():
            for child in self.children():
                if isinstance(child, ValueControl):
                    child.update_value()


class View(QtWidgets.QWidget, BaseView):
    """Add upload and update loop to QWidget"""

    def __init__(self, *args, **kwargs):
        QtWidgets.QWidget.__init__(self, *args, **kwargs)
        BaseView.__init__(self)

    def showEvent(self, event):
        """Start update loop when window is shown"""
        self.upload()
        self.update_list.start()
        event.accept()

    def closeEvent(self, event):
        """Stop update loop when window is closed"""
        self.update_list.stop()
        event.accept()
A benefit of this approach is giving View and GroupView a common superclass makes them easier to find using methods like QtWidget.findChildren(BaseView).
Reply
#4
Why dont you write showEvent() and closeEvent() in the BaseView class ? You could also call it ViewMixin to clarify its role. Also there are arguments for writing the Mixin classes before the normal parent classes in the sequence of base classes.
Reply
#5
I would swear that I tried this before and it threw up all over me. Now it works fine.
class BaseView():
    """Abstract base class for views"""
    def __init__(self):
       self.update_list = UpdateList(1.0)

    def showEvent(self, event):
        """Start update loop when window is shown"""
        self.upload()
        self.update_list.start()
        event.accept()

    def closeEvent(self, event):
        """Stop update loop when window is closed"""
        self.update_list.stop()
        event.accept()

    def upload(self):
        """Forward update message to all ValueControl objects"""
        if self.isVisible():
            for child in self.children():
                if isinstance(child, ValueControl):
                    child.update_value()


class View(QtWidgets.QWidget, BaseView):
    """Add upload and update loop to QWidget"""

    def __init__(self, *args, **kwargs):
        BaseView.__init__(self)
        QtWidgets.QWidget.__init__(self, *args, **kwargs)
Reply
#6
Actually it doesn't work fine. Moving showEvent() and closeEvent() to the mixin class results in not capturing these events.
Reply
#7
The problem is that I know almost nothing in PyQt5. Do you have the same issue if you write BaseView before QWidget in the list of base classes of View ?

You could also try something like

class View...
    closeEvent = BaseView.closeEvent
Reply
#8
This discussion has been very educational. Thanks!

This works.
class BaseView():
    """Abstract base class for views"""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.update_list = UpdateList(1.0)

    def showEvent(self, event):
        """Start update loop when window is shown"""
        self.upload()
        self.update_list.start()
        event.accept()

    def closeEvent(self, event):
        """Stop update loop when window is closed"""
        self.update_list.stop()
        event.accept()

    def upload(self):
        """Forward update message to all ValueControl objects"""
        print(self)
        if self.isVisible():
            for child in self.children():
                if isinstance(child, ValueControl):
                    child.update_value()

class View(BaseView, QtWidgets.QWidget):
    """Add upload and update loop to QWidget"""

class GroupView(BaseView, QtWidgets.QGroupBox):
    """Add upload and update loop to QBoxGroup"""
Gribouillis likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Equivalent Python code from VBA Mishal0488 2 780 Apr-19-2024, 10:32 AM
Last Post: masonsbore
  What is bug template using python Anldra12 0 961 Nov-02-2021, 11:36 AM
Last Post: Anldra12
  Erreur de code python sur un template rpm de zabbix samba 0 1,920 Apr-02-2021, 09:43 AM
Last Post: samba
  Hi Guys, please help me to write SAS macro parameter equivalent code in Python Manohar9589 2 2,597 Jun-14-2020, 05:07 PM
Last Post: Larz60+
  python equivalent to MATLAB xcov chai0404 2 3,878 Apr-02-2020, 10:29 PM
Last Post: chai0404
  Python equivalent of Matlab code kwokmaster 1 3,455 Mar-25-2020, 10:14 PM
Last Post: j.crater
  Equivalent of 'bwareafilt' for Python Mighty 1 3,602 Feb-05-2020, 10:32 PM
Last Post: Marbelous
  Convert a mongo db scrip to python equivalent Herath 1 2,190 Aug-20-2019, 02:28 PM
Last Post: fishhook
  SAS Equivalent of Macro variable in Python AI_ML_Neophyte 4 11,658 Mar-29-2019, 08:14 AM
Last Post: FelixS
  Python equivalent to sed [solved] cygnus_X1 2 11,401 Sep-24-2018, 10:13 PM
Last Post: cygnus_X1

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020