As mentioned earlier, you should only emit signals from the class that owns it or from its subclasses. However, if signals were really protected or private, you would not be able to connect to them using the pointer-to-member function syntax. To make such connections possible, signals are made public functions. This means that the compiler won't stop you from calling the signal from outside. If you want to prevent such calls, you can declare QPrivateSignal as the last argument of the signal:
signals: void valueChanged(int value, QPrivateSignal);
QPrivateSignal is a private struct created in each QObject subclass by the Q_OBJECT macro, so you can only create QPrivateSignal objects in the current class.