Results 1 to 6 of 6

Thread: qobject_cast fails in slot

  1. #1
    Join Date
    Jul 2012
    Posts
    228
    Thanks
    19
    Thanked 14 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Angry qobject_cast fails in slot

    I have derived a custom widget my_widget from QWidget. There is a factory function in my MainWindow that creates those widgets, and their destroy-signal is connected to a slot in the MainWindow to do some cleanup.


    Problem: qobject_cast returns zero when I try to cast the QOjbect* the slot received to my_widget*.

    If I try the cast directly in the factory function, that works.
    If I use plain-cast in the slot, it works too (the pointer is the same as returned by tthe factory function).
    If I try to qobject_cast to a QWidget*, that works too.


    Qt Code:
    1. my_widget* create_my_widget(QWidget* parent = nullptr)
    2. {
    3. auto w = new my_widget(parent);
    4.  
    5. QObject* ppp = (QObject*)w;
    6. auto sss = qobject_cast<my_widget*>(ppp); //works!
    7.  
    8. connect(w, &my_widget::destroyed, this, &MainWindow::remove_mywidget_widget);
    9. return w;
    10. }
    To copy to clipboard, switch view to plain text mode 


    slot:

    Qt Code:
    1. void MainWindow::remove_mywidget_widget(QObject* removed)
    2. {
    3. auto mywid = qobject_cast<my_widget*>(removed); //Fails!
    4. auto mywid2 = my_widget::staticMetaObject.cast(removed); //Fails!
    5. auto mywid3 = qobject_cast<QWidget*>(removed); //Works!
    6. auto mywid4 = (my_widget*)removed; //Works!
    7.  
    8. ...
    9.  
    10. }
    To copy to clipboard, switch view to plain text mode 


    Where am I going wrong?

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,481
    Thanks
    252
    Thanked 711 Times in 701 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: qobject_cast fails in slot

    I wonder if the problem is that the C++ object type system is failing to correctly deduce the return type of the qobject_cast<>() template when you assign the result to a variable defined as auto? What happens if you replace auto with my_widget * ?

    Do you have the Q_OBJECT macro included in your definition of the my_widget class?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jul 2012
    Posts
    228
    Thanks
    19
    Thanked 14 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: qobject_cast fails in slot

    Sadly that isnt the problem. Yes, the Q_OBJECT macro is there.

    I have created a minimal demo to reproduce the issue:


    Qt Code:
    1. class my_wid : public QWidget
    2. {
    3. Q_OBJECT
    4. public:
    5. my_wid(QWidget* p=0) : QWidget(p)
    6. {}
    7.  
    8. int a,b,c;
    9. };
    10.  
    11. class MainWindow : public QMainWindow
    12. {
    13. Q_OBJECT
    14.  
    15. public:
    16. explicit MainWindow(QWidget *parent = 0)
    17. {
    18. my_wid* mm = create_mywid();
    19. delete mm;
    20. }
    21.  
    22. my_wid* create_mywid(QWidget* parent=0)
    23. {
    24. my_wid* w = new my_wid(parent);
    25. connect(w, &QObject::destroyed, this, &MainWindow::remove_mywid);
    26. return w;
    27. }
    28.  
    29.  
    30. protected slots:
    31.  
    32. void remove_mywid(QObject* removed)
    33. {
    34. my_wid* test = qobject_cast<my_wid*>(removed);
    35. qDebug() << test; // is 0 :(
    36. }
    37. };
    To copy to clipboard, switch view to plain text mode 

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,481
    Thanks
    252
    Thanked 711 Times in 701 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: qobject_cast fails in slot

    Strange. Here's another experiment: Instead of destroying the widget in the MainWindow constructor, set up a one-shot QTimer and connect the timeout() signal to my_wid's deleteLater() slot.

    This may possibly be some quirk of Qt that because the MainWindow constructor hasn't finished before you delete the my_wid instance, all of the necessary internal wiring isn't set up completely.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Jul 2012
    Posts
    228
    Thanks
    19
    Thanked 14 Times in 13 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: qobject_cast fails in slot

    No change.
    In my real-world use case the destruction of the my_widget is also user-initiated and that doesnt work either. Really strange.

    Qt Code:
    1. QTimer::singleShot(2000, mm, &my_wid::deleteLater);
    To copy to clipboard, switch view to plain text mode 

  6. The following user says thank you to tuli for this useful post:

    d_stranz (26th July 2018)

  7. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,481
    Thanks
    252
    Thanked 711 Times in 701 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: qobject_cast fails in slot

    No idea. Do you have the header file for my_widget #included so that MainWindow sees the full class definition (and not just a forward declaration of "class my_widget")? You must, otherwise your factory method wouldn't work. I don't think the qobject_cast<> template would compile without the full definition either. The static cast would work, though, because it just forces the compiler to treat a pointer to "x" as a pointer to "y" and won't complain until you try to call some member function of "y".
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. qobject_cast
    By valgaba in forum Qt Programming
    Replies: 1
    Last Post: 18th March 2014, 16:29
  2. Replies: 0
    Last Post: 20th March 2013, 10:02
  3. Replies: 2
    Last Post: 7th August 2011, 11:50
  4. qobject_cast fails across dynamic library boundaries
    By JPNaude in forum Qt Programming
    Replies: 9
    Last Post: 30th December 2008, 17:36
  5. qobject_cast for Qt3 ?
    By sunil.thaha in forum Qt Programming
    Replies: 3
    Last Post: 18th December 2006, 05:12

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.