Results 1 to 12 of 12

Thread: Signal/Slots with PIMPL

  1. #1
    Join Date
    Aug 2011
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Signal/Slots with PIMPL

    I try to use Qts Signal/Slot mechanism with private implementation (PIMPL).

    My header file is build like:
    Qt Code:
    1. class Foo : public QWidget
    2. {
    3. Q_OBJECT
    4. public:
    5. ...
    6. private:
    7. class FooPrivate;
    8. FooPrivate *d;
    9. }
    To copy to clipboard, switch view to plain text mode 

    My source file is build like:
    Qt Code:
    1. Foo::FooPrivate : public QWidget
    2. {
    3. public:
    4. ...
    5. public slots:
    6. void doSomething();
    7. signals:
    8. void emitSomething();
    9. }
    To copy to clipboard, switch view to plain text mode 

    Due to this private implementation, the private signals and slots are declared inside the source file and not recognized by Q_OBJECT.

    Is there an other way to use the signal/slot mechanism inside a local class?

    Thanks

    Kai

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Signal/Slots with PIMPL

    the private signals and slots are declared inside the source file and not recognized by Q_OBJECT.
    Did you really meant what you wrote here?
    Your code clearly declares the signals/slots of your private class in the header.
    And if you add the Q_OBJECT macro to your private class, it should compile as well.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Aug 2011
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Signal/Slots with PIMPL

    Qt ignores the signals and slotes defined in my source.cpp as they have to be defined in the source.h.

    If I add another Q_OBJECT inside Foo::FooPrivate I got a lot of Linker errors.

  4. #4
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signal/Slots with PIMPL

    You declared FooPrivate in a source (.cpp) file, which hides it from moc. You have to move it to a header (.h) file. The convention in the Qt sources is to add the "_p" suffix to the file name to denote that it is a private header meant to be parsed by moc but not directly included by the user. In your case you would have e.g. Foo.h, Foo.cpp, and Foo_p.h.

    Also I am not sure that moc supports inner classes. You might have to move FooPrivate out of Foo.

  5. #5
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Signal/Slots with PIMPL

    Qt ignores the signals and slotes defined in my source.cpp as they have to be defined in the source.h.
    The signals have to be declared in the header.
    The slots as well.

    The slots have to be defined in the source file.

    If I add another Q_OBJECT inside Foo::FooPrivate I got a lot of Linker errors.
    Show the errors you get.

    EDIT:
    Ah, i just now noticed this:
    My source file is build like:
    The class declaration has to be in a header file.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  6. #6
    Join Date
    Aug 2011
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: Signal/Slots with PIMPL

    Quote Originally Posted by yeye_olive View Post
    You declared FooPrivate in a source (.cpp) file, which hides it from moc. You have to move it to a header (.h) file. The convention in the Qt sources is to add the "_p" suffix to the file name to denote that it is a private header meant to be parsed by moc but not directly included by the user. In your case you would have e.g. Foo.h, Foo.cpp, and Foo_p.h.

    Also I am not sure that moc supports inner classes. You might have to move FooPrivate out of Foo.
    But am I right that I have to deliver Foo_p.h if someone wants to use my Foo.h with Foo.dll???

  7. #7
    Join Date
    Oct 2009
    Posts
    483
    Thanked 97 Times in 94 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Signal/Slots with PIMPL

    Quote Originally Posted by kwalle View Post
    But am I right that I have to deliver Foo_p.h if someone wants to use my Foo.h with Foo.dll???
    I believe it would not be necessary to distribute Foo_p.h to the users of the library.

  8. #8
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Signal/Slots with PIMPL

    Well the whole PIMPL approach is a bit senseless if you expose the nature of your private class in the *.h file. You can declare it the cpp file but then add
    Qt Code:
    1. #include "foo.moc"
    To copy to clipboard, switch view to plain text mode 
    at the end of the file, that it is recognized by the MOC compiler.

  9. #9
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Signal/Slots with PIMPL

    You can declare it the cpp file but then add
    For that you first need to have the moc file, which is generated by the moc compiler...
    If you want to use Q_OBJECT you will have first to have this in a header, run moc on it, and then add #include "foo.moc".
    AFAIK at least.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  10. #10
    Join Date
    Jan 2006
    Location
    Germany
    Posts
    4,380
    Thanks
    19
    Thanked 1,005 Times in 913 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60
    Wiki edits
    5

    Default Re: Signal/Slots with PIMPL

    On my side this works perfect:

    Qt Code:
    1. //main.cpp
    2. #include <QtCore>
    3. #include "outer.h"
    4.  
    5. int main(int argc, char *argv[])
    6. {
    7. QCoreApplication a(argc, argv);
    8.  
    9. Outer o;
    10. QTimer::singleShot(1000, &a, SLOT(quit()));
    11.  
    12. return a.exec();
    13. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. //outer.h
    2. #ifndef OUTER_H
    3. #define OUTER_H
    4.  
    5. #include <QObject>
    6. class Inner;
    7.  
    8. class Outer : public QObject
    9. {
    10. Q_OBJECT
    11. public:
    12. explicit Outer(QObject *parent = 0);
    13. public Q_SLOTS:
    14. void mySlot();
    15. private:
    16. Inner* m_inner;
    17. };
    18.  
    19. #endif // OUTER_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. //outer.cpp
    2. #include "outer.h"
    3.  
    4. #include <QtCore>
    5.  
    6.  
    7. class Inner : public QObject
    8. {
    9. Q_OBJECT
    10. public:
    11. Inner(QObject *p) : QObject(p) {}
    12. Q_SIGNALS:
    13. void mySignal();
    14. public:
    15. void emitMySignal() {Q_EMIT mySignal();}
    16. };
    17.  
    18. Outer::Outer(QObject *parent) :
    19. QObject(parent)
    20. {
    21. m_inner = new Inner(this);
    22. connect(m_inner, SIGNAL(mySignal()), this, SLOT(mySlot()));
    23. m_inner->emitMySignal();
    24. }
    25.  
    26. void Outer::mySlot()
    27. {
    28. qWarning() << Q_FUNC_INFO;
    29. }
    30.  
    31. #include "outer.moc"
    To copy to clipboard, switch view to plain text mode 

    And don't forget to rerun qmake...

  11. #11
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Signal/Slots with PIMPL

    Here is a magic trick:
    Qt Code:
    1. // foo.h
    2. class Foo : public QWidget
    3. {
    4. Q_OBJECT
    5. public:
    6. ...
    7. private:
    8. class FooPrivate;
    9. FooPrivate *d;
    10. Q_PRIVATE_SLOT(d, void doSomething());
    11. };
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. //foo.cpp
    2. #include "foo.h"
    3. class FooPrivate {
    4. public:
    5. void doSomething() { qDebug() << Q_FUNC_INFO; }
    6. };
    7.  
    8. #include "foo.moc" // this does the magic
    To copy to clipboard, switch view to plain text mode 

    Then you can do:
    Qt Code:
    1. Foo foo;
    2. connect(something, SIGNAL(...), &foo, SLOT(doSomething()));
    To copy to clipboard, switch view to plain text mode 
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  12. #12
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Signal/Slots with PIMPL

    @Lykurg:
    //main.cpp
    #include <QtCore>
    #include "outer.h"
    Ok, now I see what you meant... :-)
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

Similar Threads

  1. Doubts on signal and slots
    By divanshu in forum Newbie
    Replies: 2
    Last Post: 27th June 2011, 11:32
  2. Signal/Slots, Where can i use it?
    By Tio in forum Newbie
    Replies: 2
    Last Post: 25th May 2010, 02:36
  3. Signal and Slots
    By waynew in forum Newbie
    Replies: 3
    Last Post: 20th November 2009, 04:50
  4. signal and slots
    By vermarajeev in forum Qt Programming
    Replies: 4
    Last Post: 16th October 2007, 09:31
  5. Signal and slots
    By villy in forum Qt Programming
    Replies: 1
    Last Post: 12th January 2007, 11:10

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.