Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. State of QPrivateSignal

State of QPrivateSignal

Scheduled Pinned Locked Moved Solved General and Desktop
19 Posts 7 Posters 2.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sakars
    wrote on last edited by
    #1

    Hi!

    I'd like to know what is the status of QPrivateSignal in modern Qt.
    Is its usage recommended and does it perform its function as expected?

    As far as I can see, there isn't any documentation in Signals & Slots page, nor QObject, nor QMetaObject docs.

    I could only find a forum post from 2021 about how QPrivateSignal can be sidestepped making the signal still be publicly callable.

    I really like the idea of making signals emittable only from inside the class, meaning that all signals called are absolutely intended by the class, leaving no chance of someone abusing them, but the lack of documentation makes me want to avoid using them.

    1 Reply Last reply
    0
    • GrecKoG Offline
      GrecKoG Offline
      GrecKo
      Qt Champions 2018
      wrote on last edited by
      #7

      The above is needlessly complicated.

      If Outer owns Helper, connect Helper::helperSignal to Outer::onHelperSignal and is the one calling Helper::helperSignal, that's a lot of indirection over calling onHelperSignal directly.

      @Sakars Don't use QPrivateSignal, relying on the convention that you shouldn't emit a signal that's not yours should be enough unless you have a specific scenario you want to avoid. Code can be abused with or without that.

      J.HilkJ S 2 Replies Last reply
      1
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        No documentation = not for public use = don't blame anyone if you use it but it breaks your code in the future.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        4
        • S Offline
          S Offline
          Sakars
          wrote on last edited by
          #3

          Huh, alright.
          Are there any documented alternatives to making signals only private/protected-ly emittable?

          J.HilkJ Pl45m4P 2 Replies Last reply
          0
          • S Sakars

            Huh, alright.
            Are there any documented alternatives to making signals only private/protected-ly emittable?

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #4

            @Sakars I would not recommend inheriting private from QObject. There are a couple of mechanisms that rely on public function access.

            But you could make a helper class with signals only. Make that a private/protected member instance of your class and use that for your "private" signals/connects


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            S 1 Reply Last reply
            3
            • J.HilkJ J.Hilk

              @Sakars I would not recommend inheriting private from QObject. There are a couple of mechanisms that rely on public function access.

              But you could make a helper class with signals only. Make that a private/protected member instance of your class and use that for your "private" signals/connects

              S Offline
              S Offline
              Sakars
              wrote on last edited by
              #5

              @J-Hilk Inheriting from QObject privately hadn't even crossed my mind as an option and it's not something I want/need to do.

              But you could make a helper class with signals only. Make that a private/protected member instance of your class and use that for your "private" signals/connects

              Interesting... How would this look in-code? A const getter method on the class, that returns a const ref to the member helper class instance to provide access for connecting signals? Can you not emit a member signal from a const ref?
              I assume this helper class would also have to inherit from QObject, is that correct?

              J.HilkJ 1 Reply Last reply
              0
              • S Sakars

                @J-Hilk Inheriting from QObject privately hadn't even crossed my mind as an option and it's not something I want/need to do.

                But you could make a helper class with signals only. Make that a private/protected member instance of your class and use that for your "private" signals/connects

                Interesting... How would this look in-code? A const getter method on the class, that returns a const ref to the member helper class instance to provide access for connecting signals? Can you not emit a member signal from a const ref?
                I assume this helper class would also have to inherit from QObject, is that correct?

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #6

                @Sakars

                #include <QObject>
                #include <QDebug>
                
                // Helper class with only signals, inaccessible from outside
                class Helper : public QObject {
                    Q_OBJECT
                
                public:
                    explicit Helper(QObject *parent = nullptr) : QObject(parent) {}
                
                signals:
                    void helperSignal(); // Internal signal only accessible by Outer
                };
                
                // Outer class that owns and controls the helper instance
                class Outer : public QObject {
                    Q_OBJECT
                
                public:
                    explicit Outer(QObject *parent = nullptr) : QObject(parent), m_helper(new Helper(this)) {
                        // Connect the helper signal to a slot in this class
                        connect(m_helper, &Helper::helperSignal, this, &Outer::onHelperSignal);
                    }
                
                protected:
                    // Internal function to trigger the helper's signal
                    void emitHelperSignal() {
                        emit m_helper->helperSignal();
                    }
                
                private slots:
                    void onHelperSignal() {
                        qDebug() << "Outer: Received helper signal!";
                    }
                
                private:
                    Helper *m_helper; // Private helper instance
                };
                
                // Main function to test the setup
                int main(int argc, char *argv[]) {
                    QCoreApplication app(argc, argv);
                
                    Outer outer;
                
                    // The signal is fully encapsulated. Only the Outer class can trigger it.
                    outer.emitHelperSignal(); // Testing encapsulation
                
                    return app.exec();
                }
                
                #include "main.moc"
                
                

                Caution, AI generated code


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                S 1 Reply Last reply
                0
                • GrecKoG Offline
                  GrecKoG Offline
                  GrecKo
                  Qt Champions 2018
                  wrote on last edited by
                  #7

                  The above is needlessly complicated.

                  If Outer owns Helper, connect Helper::helperSignal to Outer::onHelperSignal and is the one calling Helper::helperSignal, that's a lot of indirection over calling onHelperSignal directly.

                  @Sakars Don't use QPrivateSignal, relying on the convention that you shouldn't emit a signal that's not yours should be enough unless you have a specific scenario you want to avoid. Code can be abused with or without that.

                  J.HilkJ S 2 Replies Last reply
                  1
                  • GrecKoG GrecKo

                    The above is needlessly complicated.

                    If Outer owns Helper, connect Helper::helperSignal to Outer::onHelperSignal and is the one calling Helper::helperSignal, that's a lot of indirection over calling onHelperSignal directly.

                    @Sakars Don't use QPrivateSignal, relying on the convention that you shouldn't emit a signal that's not yours should be enough unless you have a specific scenario you want to avoid. Code can be abused with or without that.

                    J.HilkJ Offline
                    J.HilkJ Offline
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #8

                    @GrecKo said in State of QPrivateSignal:

                    The above is needlessly complicated.

                    If Outer owns Helper, connect Helper::helperSignal to Outer::onHelperSignal and is the one calling Helper::helperSignal, that's a lot of indirection over calling onHelperSignal directly.

                    of course it is, but thats beside the point op, wanted a solution for "private" signals without using "QPrivateSignal" and I spouted ideas.

                    There are days when I like to delve into the rabbit hole :D


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    1 Reply Last reply
                    0
                    • GrecKoG Offline
                      GrecKoG Offline
                      GrecKo
                      Qt Champions 2018
                      wrote on last edited by
                      #9

                      That's not what's requested though. A private signal is a signal that you can't emit from outside but can still connect to.

                      J.HilkJ 1 Reply Last reply
                      1
                      • GrecKoG GrecKo

                        That's not what's requested though. A private signal is a signal that you can't emit from outside but can still connect to.

                        J.HilkJ Offline
                        J.HilkJ Offline
                        J.Hilk
                        Moderators
                        wrote on last edited by
                        #10

                        @GrecKo yes, what's your point?


                        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                        Q: What's that?
                        A: It's blue light.
                        Q: What does it do?
                        A: It turns blue.

                        1 Reply Last reply
                        0
                        • GrecKoG GrecKo

                          The above is needlessly complicated.

                          If Outer owns Helper, connect Helper::helperSignal to Outer::onHelperSignal and is the one calling Helper::helperSignal, that's a lot of indirection over calling onHelperSignal directly.

                          @Sakars Don't use QPrivateSignal, relying on the convention that you shouldn't emit a signal that's not yours should be enough unless you have a specific scenario you want to avoid. Code can be abused with or without that.

                          S Offline
                          S Offline
                          Sakars
                          wrote on last edited by
                          #11

                          @GrecKo

                          Don't use QPrivateSignal, relying on the convention that you shouldn't emit a signal that's not yours should be enough unless you have a specific scenario you want to avoid. Code can be abused with or without that.

                          As it is with ageing projects with multiple people coming and going, some new to Qt, relying on that people will keep abiding by convention isn't always enough. I know it's futile, but seeing as the project I'm working on already breaks this convention, I'm trying to find if there's some ways to at least improve the maintainability and somewhat future-proof at least some signals.

                          1 Reply Last reply
                          0
                          • J.HilkJ J.Hilk

                            @Sakars

                            #include <QObject>
                            #include <QDebug>
                            
                            // Helper class with only signals, inaccessible from outside
                            class Helper : public QObject {
                                Q_OBJECT
                            
                            public:
                                explicit Helper(QObject *parent = nullptr) : QObject(parent) {}
                            
                            signals:
                                void helperSignal(); // Internal signal only accessible by Outer
                            };
                            
                            // Outer class that owns and controls the helper instance
                            class Outer : public QObject {
                                Q_OBJECT
                            
                            public:
                                explicit Outer(QObject *parent = nullptr) : QObject(parent), m_helper(new Helper(this)) {
                                    // Connect the helper signal to a slot in this class
                                    connect(m_helper, &Helper::helperSignal, this, &Outer::onHelperSignal);
                                }
                            
                            protected:
                                // Internal function to trigger the helper's signal
                                void emitHelperSignal() {
                                    emit m_helper->helperSignal();
                                }
                            
                            private slots:
                                void onHelperSignal() {
                                    qDebug() << "Outer: Received helper signal!";
                                }
                            
                            private:
                                Helper *m_helper; // Private helper instance
                            };
                            
                            // Main function to test the setup
                            int main(int argc, char *argv[]) {
                                QCoreApplication app(argc, argv);
                            
                                Outer outer;
                            
                                // The signal is fully encapsulated. Only the Outer class can trigger it.
                                outer.emitHelperSignal(); // Testing encapsulation
                            
                                return app.exec();
                            }
                            
                            #include "main.moc"
                            
                            

                            Caution, AI generated code

                            S Offline
                            S Offline
                            Sakars
                            wrote on last edited by
                            #12

                            @J-Hilk Correct me if I'm wrong but I don't see any way an arbitrary outside class could connect its own slot to the internal signal defined in Helper.

                            J.HilkJ 1 Reply Last reply
                            0
                            • S Sakars

                              @J-Hilk Correct me if I'm wrong but I don't see any way an arbitrary outside class could connect its own slot to the internal signal defined in Helper.

                              J.HilkJ Offline
                              J.HilkJ Offline
                              J.Hilk
                              Moderators
                              wrote on last edited by
                              #13

                              @Sakars as long as you don't expose the helper instance to the outside, via it being public or via getter, than no, there is no way to connect the the helper signal outside the class


                              Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                              Q: What's that?
                              A: It's blue light.
                              Q: What does it do?
                              A: It turns blue.

                              S 1 Reply Last reply
                              0
                              • J.HilkJ J.Hilk

                                @Sakars as long as you don't expose the helper instance to the outside, via it being public or via getter, than no, there is no way to connect the the helper signal outside the class

                                S Offline
                                S Offline
                                Sakars
                                wrote on last edited by
                                #14

                                @J-Hilk Then I don't think this fits my ideal solution. Ideally a private/protected signal would have these properties:

                                • Any arbitrary class can connect to this signal without asking for "consent" from the class itself (i.e. you should be able to connect to it even if all you have is a constant reference to the instance)
                                • Any arbitrary class cannot emit the signal of this class directly even if they have a mutable reference to it.
                                • The class instance can emit its own (or any other instance of this class') signal the same way you can call a protected/private method.
                                1 Reply Last reply
                                0
                                • J.HilkJ Offline
                                  J.HilkJ Offline
                                  J.Hilk
                                  Moderators
                                  wrote on last edited by J.Hilk
                                  #15

                                  ok,
                                  fine

                                  make your own private signal than:

                                  class MyClass : public QObject{
                                      Q_OBJECT
                                      
                                      struct PrivatSignal{};
                                  public:
                                      MyClass(QObject*parent = nullptr) : QObject(parent) {}
                                      
                                      
                                  signals:
                                      void myPrivateSignal(PrivatSignal); // == to void argument signal
                                  };
                                  

                                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                                  Q: What's that?
                                  A: It's blue light.
                                  Q: What does it do?
                                  A: It turns blue.

                                  1 Reply Last reply
                                  1
                                  • S Sakars has marked this topic as solved on
                                  • S Sakars

                                    Huh, alright.
                                    Are there any documented alternatives to making signals only private/protected-ly emittable?

                                    Pl45m4P Offline
                                    Pl45m4P Offline
                                    Pl45m4
                                    wrote on last edited by
                                    #16

                                    @Sakars said in State of QPrivateSignal:

                                    Are there any documented alternatives to making signals only private/protected-ly emittable?

                                    I don't understand the struggle :)
                                    Event the suggested solutions here seem like overkill...

                                    private:
                                        Q_SIGNAL void privateSignal();
                                    

                                    Done.

                                    // works in Foo.cpp
                                    emit this->privateSignal(); 
                                    
                                    // not in class = does not work
                                    Foo foo;
                                    emit foo->privateSignal();
                                    

                                    Latter throws:

                                    \main.cpp:42: Error: 'privateSignal' is a private member of 'Foo'


                                    If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                                    ~E. W. Dijkstra

                                    JonBJ GrecKoG 2 Replies Last reply
                                    1
                                    • Pl45m4P Pl45m4

                                      @Sakars said in State of QPrivateSignal:

                                      Are there any documented alternatives to making signals only private/protected-ly emittable?

                                      I don't understand the struggle :)
                                      Event the suggested solutions here seem like overkill...

                                      private:
                                          Q_SIGNAL void privateSignal();
                                      

                                      Done.

                                      // works in Foo.cpp
                                      emit this->privateSignal(); 
                                      
                                      // not in class = does not work
                                      Foo foo;
                                      emit foo->privateSignal();
                                      

                                      Latter throws:

                                      \main.cpp:42: Error: 'privateSignal' is a private member of 'Foo'

                                      JonBJ Offline
                                      JonBJ Offline
                                      JonB
                                      wrote on last edited by
                                      #17

                                      @Pl45m4 Q_SIGNAL wasn't available 15 years ago and you couldn't make them private :)

                                      1 Reply Last reply
                                      0
                                      • Pl45m4P Pl45m4

                                        @Sakars said in State of QPrivateSignal:

                                        Are there any documented alternatives to making signals only private/protected-ly emittable?

                                        I don't understand the struggle :)
                                        Event the suggested solutions here seem like overkill...

                                        private:
                                            Q_SIGNAL void privateSignal();
                                        

                                        Done.

                                        // works in Foo.cpp
                                        emit this->privateSignal(); 
                                        
                                        // not in class = does not work
                                        Foo foo;
                                        emit foo->privateSignal();
                                        

                                        Latter throws:

                                        \main.cpp:42: Error: 'privateSignal' is a private member of 'Foo'

                                        GrecKoG Offline
                                        GrecKoG Offline
                                        GrecKo
                                        Qt Champions 2018
                                        wrote on last edited by
                                        #18

                                        @Pl45m4 said in State of QPrivateSignal:

                                        I don't understand the struggle :)
                                        Event the suggested solutions here seem like overkill...

                                        It's not possible to connect to your private Q_SIGNAL from outside of the class. That's the requirement.

                                        1 Reply Last reply
                                        2
                                        • H Offline
                                          H Offline
                                          Humfridbjorn
                                          wrote on last edited by
                                          #19
                                          This post is deleted!
                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved