Qt "private slots:" what is this?
Asked Answered
C

4

98

I understand how to use it, but the syntax of it bothers me. What is "private slots:" doing?

I have never seen something between the private keyword and the : in a class definition before. Is there some fancy C++ magic going on here?

And example here:

 #include <QObject>

 class Counter : public QObject
 {
     Q_OBJECT

 public:
     Counter() { m_value = 0; }

     int value() const { return m_value; }

 public slots:
     void setValue(int value);

 ...
Cloaca answered 5/2, 2012 at 7:19 Comment(3)
This is not Standard C++, This is QT framework construct. Lookup QT signals and slots.Teach
When compiling as C++ slots is defined as #define slots. When compiling using Qt MOC it generates code for the C++ compiler.Eratosthenes
lol this was even harder for me to understand because i havent used C++ in so long, i thought they added something newHydrodynamics
D
61

Slots are a Qt-specific extension of C++. It only compiles after sending the code through Qt's preprocessor, the Meta-Object Compiler (moc). See http://doc.qt.io/qt-5/moc.html for documentation.

Edit: As Frank points out, moc is only required for linking. The extra keywords are #defined away with the standard preprocessor.

Dauntless answered 5/2, 2012 at 7:31 Comment(4)
Thanks, Qt's preprocessor is what I was missing in my mental model of what was going on.Cloaca
Not correct, the code compiles all the time as "signals" and "slots" are empty defines so the compiler never sees them. These macros are hints for moc, which generates additional code. The original .h and .cpp files are not altered and compile just fine without moc. What would fail is linking, as the moc-generated definitions (signal definitions, metaobject, etc.) are otherwise missing.Sermonize
Is the slots keyword necessary? I've tried compiling/linking a few tiny Qt programs that call slots without the slots keyword and they have built just fine. My experiments show that: signals: is definitely necessary, slots might be unnecessary, and emit seems to be unnecessary as I've read elsewhere.Ayeaye
slots is not necessary in Qt5. Qt updated the connect() syntax to allow for connecting a signal to an arbitrary function, including lambdas. Because of this, slots is not necessary. However, the slots keyword still affects the way that an object's QMetaObject is built. moc (aka, the "meta-object compiler") won't recognize a method as a slot unless it is within the slots: section of a class definition. So, although the connection will still work, the method will not show up in introspection tools.Wyatt
D
22

The keywords such as public, private are ignored for Qt slots. All slots are actually public and can be connected

Douglassdougy answered 5/2, 2012 at 7:29 Comment(3)
When the method is called via signal/slot mechanism, the access specifiers are ignored. But slots are also "normal" methods. When you call them using the traditional way, the access specifiers are considered.Deviltry
@Deviltry and any future readers. In Qt5 the connect() method can use function pointers (which has advantages). If you connect with function pointers then the access specifiers are enforced in the signals/slots mechanism.Virgilio
@Deviltry I believe this is incorrect, or at least the explanation was unclear. The access specifiers do not restrict your ability to connect signals to slots; that is, a private slot can be connected to any signal. The access specifier does, however, protect the member function from its class (in the typical way) while it's being invoked. So, the access specifiers aren't "ignored" when called via the signal/slot mechanism: they have no bearing on connecting slots to signals, but they do protect the function from this in the way we are familiar with.Ayeaye
D
4

Declaring slots as private means that you won't be able to reference them from context in which they are private, like any other method. Consequently you won't be able to pass private slots address to connect.

If you declare signal as private you are saying that only this class can manage it but function member pointers do not have access restrictions:

class A{
    private:
    void e(){

    }
    public:
    auto getPointer(){
        return &A::e;   
    }
};

int main()
{
    A a;
    auto P=a.getPointer();
    (a.*P)();
}

Other than that, what other answers mention is valid too:
- you still can connect private signals and slots from outside with tricks
- signals and slots are empty macros and do not break language standard

Dingdong answered 23/2, 2017 at 19:29 Comment(5)
Why does this question not have any upvotes? Is there something wrong with it? I find the statement, that slots is a macro helpful. I cannot connect private slot-function-pointers to connect without tricks, can I?Overshadow
@Overshadow function member pointers do not have access restrictions.Dingdong
I think "Consequently you won't be able to pass private slots address to connect." contradicts @Douglassdougy answer (which I think is the clearest), isn't?Himyarite
@Himyarite you can connect any signals and slots you want regardless of their relationship between each other - if you have their pointers. That does not change the fact that you cannot reference private slots and signals by their identifier when they are not visible. I do not remember exactly but even using text strings as identifiers probably does not work either.Dingdong
Because it expands into the reference to the actual signal or slot requested.Dingdong
H
1

If we are going to call slots using the connect mechanism, then we declare them as public slots.

If we are not going to call them using the connect mechanism, then we do not declare them as slots.

If we are considering to call them both ways, may be its time for refactoring to fit in previous cases.

That's how I used to think.

Throughout the Qt documentation I see them as public. Just spot one place though where private slots are mentioned

Note: You need to include the QTest header and declare the test functions as private slots so the test framework finds and executes it.

Himyarite answered 20/2, 2023 at 15:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.