Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to emit parentWidget's signal from its child?
Qt 6.12 LTS is out! See what's new in the release blog

How to emit parentWidget's signal from its child?

Scheduled Pinned Locked Moved Solved General and Desktop
25 Posts 5 Posters 8.7k Views 3 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.
  • JonBJ JonB

    @Emon-Haque said in How to emit parentWidget's signal from its child?:

    BUT s got it right

    No, it did not! As I wrote, with static_cast<> " does not check or return nullptr, it takes your word for it. " But here you apparently lied to it, because the other two tell you that parentWidget() is not a QueryWidget*. So goodness knows what happens when you then go w->noSelect(). Do not use static_cast<>!

    So what is your QueryResultView, and what is its parentWidget() or parent()?

    Ah: queryresult = new QueryResultView(this);, so its parent should be a QueryWidget.

    Not[e] in both cases, parentWidget() and parent() the o and d are null

    I give up. parent() at least should be QueryWidget*. What class is QueryResultView derived from?

    Instead of puzzling over whether a signal is emitted, and whether that is connected to your slot, try calling some direct method of QueryWidget on the cast-pointer where you can check its result. For example, you could setObjectName() on queryWidget and then verify what a later objectName() off your pointer actually returns.

    ? Offline
    ? Offline
    A Former User
    wrote on last edited by A Former User
    #5

    @JonB, class QueryResultView : public QWidget { ... };

    EDIT
    Here's another snapshot with both parent() and parentWidget():

    cap2.PNG

    JonBJ 1 Reply Last reply
    0
    • ? A Former User

      @JonB, class QueryResultView : public QWidget { ... };

      EDIT
      Here's another snapshot with both parent() and parentWidget():

      cap2.PNG

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

      @Emon-Haque

      Instead of puzzling over whether a signal is emitted, and whether that is connected to your slot, try calling some direct method of QueryWidget on the cast-pointer where you can check its result. For example, you could setObjectName() on queryWidget and then verify what a later objectName() off your pointer actually returns.

      ? 1 Reply Last reply
      0
      • JonBJ JonB

        @Emon-Haque

        Instead of puzzling over whether a signal is emitted, and whether that is connected to your slot, try calling some direct method of QueryWidget on the cast-pointer where you can check its result. For example, you could setObjectName() on queryWidget and then verify what a later objectName() off your pointer actually returns.

        ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #7

        @JonB, it:

        auto os = static_cast<QueryWidget*>(parentWidget());
        os->setObjectName("Test");
        os = static_cast<QueryWidget*>(parentWidget());
        qDebug() << os->objectName();
        

        prints Test

        JonBJ 1 Reply Last reply
        0
        • ? A Former User

          @JonB, it:

          auto os = static_cast<QueryWidget*>(parentWidget());
          os->setObjectName("Test");
          os = static_cast<QueryWidget*>(parentWidget());
          qDebug() << os->objectName();
          

          prints Test

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

          @Emon-Haque
          That is not what I meant, it doesn't prove anything. The setObjectName() must be done on the actual QueryWidget instance where it is created, not in this method. We are trying to find out what the object(s) pointed to here by parentWidget() and parent() are.

          My last word: print out what is in the dynamic_cast & qobject_cast variables, do not rely on what the debugger is showing you.

          I do not know how those can be nullptr when your static_cast<> works.

          I do not not know why you can apparently call objectName() on the pointer but the signal does not seem to be emitted. You could verify that where you have an actual instance of QueryWidget (nowhere near this method, and after you have connected the slot) you can call instance->noSelect(...); so that you know that works.

          ? 1 Reply Last reply
          0
          • M Offline
            M Offline
            mpergand
            wrote on last edited by mpergand
            #9
            auto w = qobject_cast<QueryWidget*>(parentWidget());
                   
             if(w)
                    emit w->noSelect(query);
             else
                    qDebug()<<"parent() not a QueryWidget"<<parent();
            
            ? 1 Reply Last reply
            1
            • J.HilkJ Offline
              J.HilkJ Offline
              J.Hilk
              Moderators
              wrote on last edited by J.Hilk
              #10

              @Emon-Haque said in How to emit parentWidget's signal from its child?:

              parentWidget()

              first of, what is parentWidget() thats a custom function, what does it do?
              it is apparently a base QWidget function 😅, oops

              secondly, the child should not know/access functions from the parent. Thats bad design.
              Let the child emit a signal that the parent catches and forwards. You can connect signals to signals, no problem.

              thirdly are you sure all classes have the Q_OBJECT macro in the headers ? qobject_cast, at least, will misbehave/not work if its missing.


              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.

              M ? 2 Replies Last reply
              3
              • J.HilkJ J.Hilk

                @Emon-Haque said in How to emit parentWidget's signal from its child?:

                parentWidget()

                first of, what is parentWidget() thats a custom function, what does it do?
                it is apparently a base QWidget function 😅, oops

                secondly, the child should not know/access functions from the parent. Thats bad design.
                Let the child emit a signal that the parent catches and forwards. You can connect signals to signals, no problem.

                thirdly are you sure all classes have the Q_OBJECT macro in the headers ? qobject_cast, at least, will misbehave/not work if its missing.

                M Offline
                M Offline
                mpergand
                wrote on last edited by mpergand
                #11

                @J-Hilk said in How to emit parentWidget's signal from its child?:

                first of, what is parentWidget() thats a custom function, what does it do?

                QWidget *QWidget::parentWidget() const
                Returns the parent of this widget, or 0 if it does not have any parent widget.

                auto w = qobject_cast<QueryWidget*>(parentWidget());
                

                Here parent() or parentWidget() it doesn't matter because of the cast.

                1 Reply Last reply
                1
                • JonBJ JonB

                  @Emon-Haque
                  That is not what I meant, it doesn't prove anything. The setObjectName() must be done on the actual QueryWidget instance where it is created, not in this method. We are trying to find out what the object(s) pointed to here by parentWidget() and parent() are.

                  My last word: print out what is in the dynamic_cast & qobject_cast variables, do not rely on what the debugger is showing you.

                  I do not know how those can be nullptr when your static_cast<> works.

                  I do not not know why you can apparently call objectName() on the pointer but the signal does not seem to be emitted. You could verify that where you have an actual instance of QueryWidget (nowhere near this method, and after you have connected the slot) you can call instance->noSelect(...); so that you know that works.

                  ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #12

                  @JonB, looks like it returns another instance of QueryWidget. With setObjectName("Test"); in the costructor of QueryWidget, if I do:

                  auto scw = static_cast<QueryWidget*>(parentWidget());
                  auto qcw = qobject_cast<QueryWidget*>(parentWidget());
                  auto dcw = dynamic_cast<QueryWidget*>(parentWidget());
                  auto scp = static_cast<QueryWidget*>(parent());
                  auto qcp = qobject_cast<QueryWidget*>(parent());
                  auto dcp = dynamic_cast<QueryWidget*>(parent());
                  qDebug() << scw->objectName();
                  qDebug() << scp->objectName();
                  qDebug() << qcw->objectName();
                  qDebug() << qcp->objectName();
                  qDebug() << dcw->objectName();
                  qDebug() << dcp->objectName();
                  

                  it prints "", empty string, twice and then app crashes. Both qobject_cast and dynamic_cast returns nullptr?

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

                    @Emon-Haque said in How to emit parentWidget's signal from its child?:

                    parentWidget()

                    first of, what is parentWidget() thats a custom function, what does it do?
                    it is apparently a base QWidget function 😅, oops

                    secondly, the child should not know/access functions from the parent. Thats bad design.
                    Let the child emit a signal that the parent catches and forwards. You can connect signals to signals, no problem.

                    thirdly are you sure all classes have the Q_OBJECT macro in the headers ? qobject_cast, at least, will misbehave/not work if its missing.

                    ? Offline
                    ? Offline
                    A Former User
                    wrote on last edited by
                    #13

                    @J-Hilk, everywhere I've Q_OBJECT at the top like this:

                    class MyObjectName : public QWidget{
                        Q_OBJECT
                    public:
                    ...
                    

                    Yes, you get those parent()/parentWidget() from QWidget. Philosophically, it could be bad design BUT if you could do so, it'll reduce significant amount of unnecessary code bloat.

                    J.HilkJ 1 Reply Last reply
                    0
                    • M mpergand
                      auto w = qobject_cast<QueryWidget*>(parentWidget());
                             
                       if(w)
                              emit w->noSelect(query);
                       else
                              qDebug()<<"parent() not a QueryWidget"<<parent();
                      
                      ? Offline
                      ? Offline
                      A Former User
                      wrote on last edited by
                      #14

                      @mpergand, that's always null with that cast so it'll enter the else block BUT the thing that will print in else block is incorrect because:

                      QueryWidget::QueryWidget(QWidget *parent) : QWidget(parent){
                          ..
                          queryresult = new QueryResultView(this);
                          ....
                      )
                      

                      QueryWidget is indeed the parent of queryresult.

                      M 1 Reply Last reply
                      0
                      • ? A Former User

                        @mpergand, that's always null with that cast so it'll enter the else block BUT the thing that will print in else block is incorrect because:

                        QueryWidget::QueryWidget(QWidget *parent) : QWidget(parent){
                            ..
                            queryresult = new QueryResultView(this);
                            ....
                        )
                        

                        QueryWidget is indeed the parent of queryresult.

                        M Offline
                        M Offline
                        mpergand
                        wrote on last edited by
                        #15

                        @Emon-Haque said in How to emit parentWidget's signal from its child?:

                        queryresult = new QueryResultView(this);
                        ....

                        What's behind ...
                        I predicte nasty stuff here :)

                        ? 1 Reply Last reply
                        0
                        • M mpergand

                          @Emon-Haque said in How to emit parentWidget's signal from its child?:

                          queryresult = new QueryResultView(this);
                          ....

                          What's behind ...
                          I predicte nasty stuff here :)

                          ? Offline
                          ? Offline
                          A Former User
                          wrote on last edited by
                          #16

                          @mpergand, what?

                          M 1 Reply Last reply
                          0
                          • ? A Former User

                            @mpergand, what?

                            M Offline
                            M Offline
                            mpergand
                            wrote on last edited by
                            #17

                            @Emon-Haque
                            Are you sure QueryResultView is not reapparented
                            What parent() prints at the end of the constructor ?

                            ? 1 Reply Last reply
                            0
                            • M mpergand

                              @Emon-Haque
                              Are you sure QueryResultView is not reapparented
                              What parent() prints at the end of the constructor ?

                              ? Offline
                              ? Offline
                              A Former User
                              wrote on last edited by A Former User
                              #18

                              @mpergand, hmm

                              qDebug() << parent() << parentWidget();
                              QSplitter(0x425d470) QSplitter(0x425d470)
                              

                              so this actually has no meaning there! as soon as I add it in QSplitter split2->addWidget(queryresult);
                              the splitter becomes its parent. Now I'll try to work with its grand parent and will let you know what happens.

                              1 Reply Last reply
                              0
                              • M Offline
                                M Offline
                                mpergand
                                wrote on last edited by mpergand
                                #19

                                Bingo, that's what I guess from the begining !

                                void QSplitter::addWidget(QWidget *widget)
                                Adds the given widget to the splitter's layout after all the other items.
                                If widget is already in the splitter, it will be moved to the new position.
                                Note: The splitter takes ownership of the widget.

                                ? 1 Reply Last reply
                                0
                                • M mpergand

                                  Bingo, that's what I guess from the begining !

                                  void QSplitter::addWidget(QWidget *widget)
                                  Adds the given widget to the splitter's layout after all the other items.
                                  If widget is already in the splitter, it will be moved to the new position.
                                  Note: The splitter takes ownership of the widget.

                                  ? Offline
                                  ? Offline
                                  A Former User
                                  wrote on last edited by
                                  #20

                                  @mpergand, now it gets into the slot of &TableWidget::onNoSelect

                                  auto scp = static_cast<QueryWidget*>(parent()->parent());
                                  emit scp->noSelect(query);
                                  qDebug() << parent()->parent() << parentWidget()->parent();
                                  

                                  and that qDebug prints:

                                  QueryWidget(0x2245c30, name = "Test") QueryWidget(0x2245c30, name = "Test")
                                  

                                  Thanks for the insight.

                                  1 Reply Last reply
                                  0
                                  • JonBJ JonB

                                    @Emon-Haque said in How to emit parentWidget's signal from its child?:

                                    BUT s got it right

                                    No, it did not! As I wrote, with static_cast<> " does not check or return nullptr, it takes your word for it. " But here you apparently lied to it, because the other two tell you that parentWidget() is not a QueryWidget*. So goodness knows what happens when you then go w->noSelect(). Do not use static_cast<>!

                                    So what is your QueryResultView, and what is its parentWidget() or parent()?

                                    Ah: queryresult = new QueryResultView(this);, so its parent should be a QueryWidget.

                                    Not[e] in both cases, parentWidget() and parent() the o and d are null

                                    I give up. parent() at least should be QueryWidget*. What class is QueryResultView derived from?

                                    Instead of puzzling over whether a signal is emitted, and whether that is connected to your slot, try calling some direct method of QueryWidget on the cast-pointer where you can check its result. For example, you could setObjectName() on queryWidget and then verify what a later objectName() off your pointer actually returns.

                                    ? Offline
                                    ? Offline
                                    A Former User
                                    wrote on last edited by
                                    #21

                                    @JonB, you asked for that parent / parentWidget BUT I didn't know at that point that If I set parent explicitly, it doesn't matter, the widget that contains my widget automatically becomes the parent.

                                    1 Reply Last reply
                                    0
                                    • ? A Former User

                                      @J-Hilk, everywhere I've Q_OBJECT at the top like this:

                                      class MyObjectName : public QWidget{
                                          Q_OBJECT
                                      public:
                                      ...
                                      

                                      Yes, you get those parent()/parentWidget() from QWidget. Philosophically, it could be bad design BUT if you could do so, it'll reduce significant amount of unnecessary code bloat.

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

                                      @Emon-Haque said in How to emit parentWidget's signal from its child?:

                                      Philosophically, it could be bad design BUT if you could do so, it'll reduce significant amount of unnecessary code bloat

                                      oh wow, are you also one of those that have everything public then?
                                      If inflexible, intervened spaghetti code is your style, fine enough.

                                      Anyway,
                                      I'm glad you got your issue solved!


                                      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
                                      • J.HilkJ J.Hilk

                                        @Emon-Haque said in How to emit parentWidget's signal from its child?:

                                        Philosophically, it could be bad design BUT if you could do so, it'll reduce significant amount of unnecessary code bloat

                                        oh wow, are you also one of those that have everything public then?
                                        If inflexible, intervened spaghetti code is your style, fine enough.

                                        Anyway,
                                        I'm glad you got your issue solved!

                                        ? Offline
                                        ? Offline
                                        A Former User
                                        wrote on last edited by A Former User
                                        #23

                                        @J-Hilk, not only public when it's simple, a couple global as well. In other framework I've spent a couple of years and tried to keep the MVVM principle everywhere and what I realized is if I keep myself stuck in those principles it makes things harder so whenever necessary/simple I get out of those.

                                        For example, if someone wants to show a dialog and want the result of the dialog for something else in some function, why would he create a dialog factory for that? Just instantiate a dialog and call show/exec in the place where necessary.

                                        1 Reply Last reply
                                        0
                                        • M Offline
                                          M Offline
                                          mchinand
                                          wrote on last edited by
                                          #24

                                          Why don't use just make a signal/slot connection between the 'child' widget and the slot of whatever other QObject you want something triggered from the 'child' object. It makes it much clearer what's happening than relying on the parent-child, or even worse, grandparent-child relationships.

                                          ? 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
                                          • Unsolved