0

I would like to know if it is possible to make a pyqtSignal() beeing a private signal of a class. The signal can be used inside the class but should not be visible outside of the class.

I tried to prefix my signal name with '_' like you can see in the code sample: my signal name is _A_valueChanged but it is still accessible by outside code of the Foo class.

import sys
from PyQt5 import QtCore
from PyQt5.QtCore import *

class Foo(QObject):
    _A_valueChanged = pyqtSignal(int)

    def __init__(self):
        super().__init__()
        self._A = 0
        self.Linked_to_A = 0

        self._A_valueChanged.connect( self.changeLinkedVar )

    @property
    def A(self):
        return self._A

    @A.setter
    def A(self, value):
        self._A = value
        self._A_valueChanged.emit(value)

    @QtCore.pyqtSlot(int)
    def changeLinkedVar( self, value ):
        print( "changeAttributeLinked " )
        self.Linked_to_A= value

if __name__ == "__main__":
    def MainNoticeThat_A_changed():
        print( "Main : foo.A has changed ")

    foo = Foo()
    foo._A_valueChanged.connect( MainNoticeThat_A_changed )

    foo.A = 5
    print( "main : foo.A = %d  ,  foo.Linked_to_A = %d " %( foo.A, foo.Linked_to_A) )

The signal _A_valueChanged is emitted in def A() of Foo class, and is well captured inside the class Foo and Foo method changeLinkedVar() is well called, updating the attribute self.Linked_to_A. That's wanted.

But in main, foo._A_valueChanged.connect( MainNoticeThat_A_changed ) is working, and MainNoticeThat_A_changed() is called. That's not wanted. I would like a python error like 'class Foo has no public signal _A_valueChanged'

jljPatch
  • 23
  • 6
  • In python nothing can be *really* made "private". There is ["name mangling"](//docs.python.org/3/tutorial/classes.html#private-variables), which involves *double* underscores, but that would just **partially** obfuscate the attribute, not make it "private". Besides, what would be your reason? The uniform access principle is a well known (and normally appreciated) aspect of Python, trying to make a signal completely private would: 1. be an exaggerated effort; 2. (besides the mangling above) extremely difficult, if not impossible; 3. probably requiring some hacky that would create more problems. – musicamante Mar 11 '23 at 23:44
  • @musicamante : thanks. Correct. I missed fundamentals. signal is like any other object. To make it _not visible_ (=partially obfuscated), I need to prefix with double _ not one _ : so, replace '_A_valueChanged' by '__A_valueChanged' and I got what I want: ```AttributeError: 'Foo' object has no attribute '__A_valueChanged'``` – jljPatch Mar 12 '23 at 07:06
  • @All experimented: this was my first question. It seems it dropps down to a duplicate : signal is like any other python object => private rule is then same : Do you adice to globally delete the full question ? – jljPatch Mar 12 '23 at 07:15
  • That's up to you, the question is closed anyway and I sincerely doubt there would be reason to open it again. – musicamante Mar 12 '23 at 13:28

0 Answers0