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. Detect top/parent move event on child widget

Detect top/parent move event on child widget

Scheduled Pinned Locked Moved Unsolved General and Desktop
qwidgetqmainwindowqmoveevent
28 Posts 6 Posters 10.5k 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.
  • mrjjM Offline
    mrjjM Offline
    mrjj
    Lifetime Qt Champion
    wrote on last edited by
    #9

    Hi
    Ahh. now i get what you ask. The reverse.
    But why would you need to know that?
    the children will move with parents automatically.

    D 1 Reply Last reply
    2
    • mrjjM mrjj

      Hi
      Ahh. now i get what you ask. The reverse.
      But why would you need to know that?
      the children will move with parents automatically.

      D Offline
      D Offline
      Dariusz
      wrote on last edited by Dariusz
      #10

      @mrjj I have created a "new" floating widget. That user can move anywhere to screenn, but at the same time widget will move in relation to specified X widget. For example it will be a button in future. Now when button moves that can be a child of Widget>dockWidget>mainWindow changing position of mainWindow, will move button to new position thus my hover widget has to move as well. Same goes if user change dockWidget position... and there can be nested hierarchy like docket>docked>docked/etc/etc... so I'm looking if there is any way at all to be notified if a widget change its screen position at any time...

      The example above shows that. where self.w is my floating widget that is meant to follow parentWidget... but when parent widget is a centralWidget of mainWindow... then the self.w no longer gets notified to change its positionw hen parentWIdget gets moved via its parent...

      1 Reply Last reply
      0
      • Christian EhrlicherC Christian Ehrlicher

        You already answered this by yourself - you know when the parent moved, so the absolute position of the child must have changed too...

        D Offline
        D Offline
        Dariusz
        wrote on last edited by
        #11

        @Christian-Ehrlicher said in Detect top/parent move event on child widget:

        You already answered this by yourself - you know when the parent moved, so the absolute position of the child must have changed too...

        I'm not sure... as far as I can tell I have to recrusively notify all widgets children+their children+their children of position/size/ change and let them all recalculate properly.... but I'm not sure if thats the best approach...

        mrjjM 1 Reply Last reply
        0
        • D Dariusz

          @Christian-Ehrlicher said in Detect top/parent move event on child widget:

          You already answered this by yourself - you know when the parent moved, so the absolute position of the child must have changed too...

          I'm not sure... as far as I can tell I have to recrusively notify all widgets children+their children+their children of position/size/ change and let them all recalculate properly.... but I'm not sure if thats the best approach...

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #12

          @Dariusz said in Detect top/parent move event on child widget:

          as far as I can tell I have to recrusively notify all widgets children+their children+their children of position/size/ change and let them all recalculate properly

          That's what Layouts normally are for. Automatic resize when parent is resized.

          Did you use layouts for the children ?

          D 1 Reply Last reply
          0
          • mrjjM mrjj

            @Dariusz said in Detect top/parent move event on child widget:

            as far as I can tell I have to recrusively notify all widgets children+their children+their children of position/size/ change and let them all recalculate properly

            That's what Layouts normally are for. Automatic resize when parent is resized.

            Did you use layouts for the children ?

            D Offline
            D Offline
            Dariusz
            wrote on last edited by
            #13

            @mrjj Yes I did, so I take I could listen to layout resizeevent/etc. But what about moveEvent?

            mrjjM 1 Reply Last reply
            0
            • Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #14

              @Dariusz said in Detect top/parent move event on child widget:

              But what about moveEvent?

              Again: they do not move - so there is no move event!

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

              D 1 Reply Last reply
              0
              • Christian EhrlicherC Christian Ehrlicher

                @Dariusz said in Detect top/parent move event on child widget:

                But what about moveEvent?

                Again: they do not move - so there is no move event!

                D Offline
                D Offline
                Dariusz
                wrote on last edited by
                #15

                @Christian-Ehrlicher So how can I detect it? Or I have to travers entire hierarchy ?

                1 Reply Last reply
                0
                • Christian EhrlicherC Online
                  Christian EhrlicherC Online
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #16

                  This was already answered.

                  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
                  1
                  • D Dariusz

                    @mrjj Yes I did, so I take I could listen to layout resizeevent/etc. But what about moveEvent?

                    mrjjM Offline
                    mrjjM Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on last edited by mrjj
                    #17

                    @Dariusz said in Detect top/parent move event on child widget:

                    @mrjj Yes I did, so I take I could listen to layout resizeevent/etc. But what about moveEvent?

                    well, you can add a new signal to the top parent and then hook up that signal
                    to all children. then in
                    parent moveEvent emit the signal to tell the children

                    But i cannot for the life of me understand why you need that.
                    If using layouts, the child will scale with Parent and a child is
                    NOT moved when a parent is moved. it stays in same position inside the parent. So no need for it to know it at all.

                    D 1 Reply Last reply
                    1
                    • mrjjM mrjj

                      @Dariusz said in Detect top/parent move event on child widget:

                      @mrjj Yes I did, so I take I could listen to layout resizeevent/etc. But what about moveEvent?

                      well, you can add a new signal to the top parent and then hook up that signal
                      to all children. then in
                      parent moveEvent emit the signal to tell the children

                      But i cannot for the life of me understand why you need that.
                      If using layouts, the child will scale with Parent and a child is
                      NOT moved when a parent is moved. it stays in same position inside the parent. So no need for it to know it at all.

                      D Offline
                      D Offline
                      Dariusz
                      wrote on last edited by
                      #18

                      @mrjj Did you look at the example above? The childWidget is not actually in layout or anything like that... he does not even have parent. Hes being moved by parentWidget() inside moveEvent... I'm trying to affect non-related widget... MoveEvent() moves its correctly... except that it does not when the parentWidget is inside another widget... So I'm trying to get that example code above work. Without having to recursively spam hundreds of widgets... Perhaps I should not name them childWidget/parentWidget :/

                      mrjjM 1 Reply Last reply
                      0
                      • Christian EhrlicherC Christian Ehrlicher

                        You already answered this by yourself - you know when the parent moved, so the absolute position of the child must have changed too...

                        D Offline
                        D Offline
                        Dariusz
                        wrote on last edited by
                        #19

                        @Christian-Ehrlicher said in Detect top/parent move event on child widget:

                        This was already answered.

                        Are you reffering to this?

                        @Christian-Ehrlicher said in Detect top/parent move event on child widget:

                        You already answered this by yourself - you know when the parent moved, so the absolute position of the child must have changed too...

                        What signal/slot/function does get called on child to notify it of new parent position ?

                        kshegunovK 1 Reply Last reply
                        0
                        • D Dariusz

                          @Christian-Ehrlicher said in Detect top/parent move event on child widget:

                          This was already answered.

                          Are you reffering to this?

                          @Christian-Ehrlicher said in Detect top/parent move event on child widget:

                          You already answered this by yourself - you know when the parent moved, so the absolute position of the child must have changed too...

                          What signal/slot/function does get called on child to notify it of new parent position ?

                          kshegunovK Offline
                          kshegunovK Offline
                          kshegunov
                          Moderators
                          wrote on last edited by
                          #20

                          @Dariusz said in Detect top/parent move event on child widget:

                          What signal/slot/function does get called on child to notify it of new parent position ?

                          None. If a widget is moved in relation to its parent's client rect (for top-level windows the "parent's client rect" is the screen), then it's going to receive a move event. Listen to that event, if you wish, by means of installing an event filter, as already mentioned.

                          There's no signal/slot/function that gets called on the children to notify of move, because that makes no sense. The parent moves, hence the rect of the widget (the non-client rect) moves, but children's rects are still left exactly the same relative to their parent's rect, so they ain't moving, hence no move event.

                          Read and abide by the Qt Code of Conduct

                          1 Reply Last reply
                          3
                          • D Dariusz

                            @mrjj Did you look at the example above? The childWidget is not actually in layout or anything like that... he does not even have parent. Hes being moved by parentWidget() inside moveEvent... I'm trying to affect non-related widget... MoveEvent() moves its correctly... except that it does not when the parentWidget is inside another widget... So I'm trying to get that example code above work. Without having to recursively spam hundreds of widgets... Perhaps I should not name them childWidget/parentWidget :/

                            mrjjM Offline
                            mrjjM Offline
                            mrjj
                            Lifetime Qt Champion
                            wrote on last edited by
                            #21

                            @Dariusz
                            Ahhhhhhhhhhh. We are talking floating widgets here :)
                            That explains a lot.

                            When you say "child" it implies it has a parent that Widget acting as a window
                            never has. (QDialog types being an exception)

                            So you on the right way with moveEvent and some signal.

                            • except that it does not when the parentWidget is inside another widget.
                              Which would make it a child. :) but in this case, it will move with the parent automatically.

                            In any case, you should be aware of
                            QApplication::topLevelWidgets()

                            that will give a list with all Windows types. those are the one, you want to move manually.

                            D 1 Reply Last reply
                            0
                            • mrjjM mrjj

                              @Dariusz
                              Ahhhhhhhhhhh. We are talking floating widgets here :)
                              That explains a lot.

                              When you say "child" it implies it has a parent that Widget acting as a window
                              never has. (QDialog types being an exception)

                              So you on the right way with moveEvent and some signal.

                              • except that it does not when the parentWidget is inside another widget.
                                Which would make it a child. :) but in this case, it will move with the parent automatically.

                              In any case, you should be aware of
                              QApplication::topLevelWidgets()

                              that will give a list with all Windows types. those are the one, you want to move manually.

                              D Offline
                              D Offline
                              Dariusz
                              wrote on last edited by
                              #22

                              @mrjj Yes I have totally failed. I should have not called it parent/child as it confused every1 and no1 has read the code :- )))

                              So I'll try to rephrase the question here...

                              Problem A:
                              I have 2 widgets.
                              WidgetA is a data widget, say QGraphicsView. - this widget can be inside layout of another widget.
                              WidgetB is a floating window, with tools.

                              The idea is that whenever WidgetA moves, the widgetB should move with it - as well as being able to move by itself - it's all in the python example above...

                              The problem is, that if WidgetA is inside layout, then it no longer informs widgetB of the new position because it don't get move events.

                              Current working "approach" that I can think off is that I have to subclass all of my widgets, and reimplement their moveEvent() & inform each child widget of new position so that they can properly handle their positioning in relationship to new parent position.

                              On another side I'm also thinking of implementing a qApp->eventFilter() - a global one, then look for moveEvent() in there and emit signals to all registered widgets from that...

                              Given that my app is "dynamically" build, meaning that parenting/widget hierarchy can change at any time, I'm looking for "automated" approach, hard coding stuff won't work here :- )

                              Problem B: (just emerged)
                              How do I et WidgetB Z depth, to be always +1 over its WidgetA so that it can be always visible above WidgetA but not visible if WidgetX moves mover it... ?

                              TIA :- )

                              1 Reply Last reply
                              0
                              • mrjjM Offline
                                mrjjM Offline
                                mrjj
                                Lifetime Qt Champion
                                wrote on last edited by
                                #23

                                @Dariusz said in Detect top/parent move event on child widget:

                                Oh yes. Words can be deceiving. I did read the code but since you said child widget i still
                                didnt get why you needed any code at all :)

                                The problem is, that if WidgetA is inside layout, then it no longer informs widgetB of the new position because it don't get move events.

                                But why must it be WidgetA ? should dit not be the top widget (the window) ?
                                Or the issue is that sometimes
                                WidgetA is a window and life is good, but then same class (WidgetA ) is used in a layout and then suddenly
                                it cant inform widgetB any more since only top parent knows it was moved ?

                                Something like that ?

                                D 1 Reply Last reply
                                0
                                • mrjjM mrjj

                                  @Dariusz said in Detect top/parent move event on child widget:

                                  Oh yes. Words can be deceiving. I did read the code but since you said child widget i still
                                  didnt get why you needed any code at all :)

                                  The problem is, that if WidgetA is inside layout, then it no longer informs widgetB of the new position because it don't get move events.

                                  But why must it be WidgetA ? should dit not be the top widget (the window) ?
                                  Or the issue is that sometimes
                                  WidgetA is a window and life is good, but then same class (WidgetA ) is used in a layout and then suddenly
                                  it cant inform widgetB any more since only top parent knows it was moved ?

                                  Something like that ?

                                  D Offline
                                  D Offline
                                  Dariusz
                                  wrote on last edited by
                                  #24

                                  I'm sorry, my bad :- ((

                                  @mrjj said in Detect top/parent move event on child widget:

                                  @Dariusz said in Detect top/parent move event on child widget:
                                  Or the issue is that sometimes
                                  WidgetA is a window and life is good, but then same class (WidgetA ) is used in a layout and then suddenly
                                  it cant inform widgetB any more since only top parent knows it was moved ?
                                  Something like that ?

                                  Yes, since its dynamically generated UI based on a user template, the WidgetA can be inside layout of another widget, or be by itself.

                                  1 Reply Last reply
                                  0
                                  • T Offline
                                    T Offline
                                    ThThoma
                                    wrote on last edited by
                                    #25

                                    I know this is an old post, but I can't seem to find a solution.

                                    To recap, I have the same problem:
                                    A floating widget (Qt::Tool | Qt::FramelessWindowHint ) that tracks another widget, let's call it the placeholder.

                                    So the placeholder is inside a layout and as such has a parent. I want the floating widget to follow the rect of the placeholder.

                                    The setup (what I know/assume) :

                                    • the floating widget has a valid pointer to the placeholder and can do anything to it.
                                    • the placeholder has a parent. So it does not receive any move events.
                                    • ideally, the solution can be achieved from within the floating/placeholder classes.

                                    My thoughts so far:

                                    1. The floating widget has a timer and periodically changes itself to follow the placeholder. -> This does not seem like a great idea, if the timer is too fast, we are wasting resources and if the timer is too slow, the user might move the window containing the placeholder, and the delay will be noticeable.
                                    2. The floating widget installs an event filter, not to catch any QEvent::Move, but to catch QEvent::WindowActivate that all the child widgets receive after a move is complete (please correct me if this is not the case). There will be a delay, yes, until the user completes the window movement but for now acceptable (cheaper than timer). -> Problem? What if the placeholder is placed inside a widget that is scrollable (QScrollArea::setWidget())? It won't receive QEvent::WindowActivate, but the placeholder parent widget (the widget inside the QScrollArea) will actually move! And this leads me to:
                                    3. The floating widget installs an event filter to the whole parent hierarchy, to catch the actual QEvent::Move . Starting from the placeholder and going up on parentWidget() until we find nullptr we install an eventFilter listening on QEvent::Move and probably to QEvent::ParentChange to fix the event filtering in case some dynamic reparenting happens. How bad of a solution is this?

                                    I'd love your feedback on this.

                                    kshegunovK 1 Reply Last reply
                                    0
                                    • T ThThoma

                                      I know this is an old post, but I can't seem to find a solution.

                                      To recap, I have the same problem:
                                      A floating widget (Qt::Tool | Qt::FramelessWindowHint ) that tracks another widget, let's call it the placeholder.

                                      So the placeholder is inside a layout and as such has a parent. I want the floating widget to follow the rect of the placeholder.

                                      The setup (what I know/assume) :

                                      • the floating widget has a valid pointer to the placeholder and can do anything to it.
                                      • the placeholder has a parent. So it does not receive any move events.
                                      • ideally, the solution can be achieved from within the floating/placeholder classes.

                                      My thoughts so far:

                                      1. The floating widget has a timer and periodically changes itself to follow the placeholder. -> This does not seem like a great idea, if the timer is too fast, we are wasting resources and if the timer is too slow, the user might move the window containing the placeholder, and the delay will be noticeable.
                                      2. The floating widget installs an event filter, not to catch any QEvent::Move, but to catch QEvent::WindowActivate that all the child widgets receive after a move is complete (please correct me if this is not the case). There will be a delay, yes, until the user completes the window movement but for now acceptable (cheaper than timer). -> Problem? What if the placeholder is placed inside a widget that is scrollable (QScrollArea::setWidget())? It won't receive QEvent::WindowActivate, but the placeholder parent widget (the widget inside the QScrollArea) will actually move! And this leads me to:
                                      3. The floating widget installs an event filter to the whole parent hierarchy, to catch the actual QEvent::Move . Starting from the placeholder and going up on parentWidget() until we find nullptr we install an eventFilter listening on QEvent::Move and probably to QEvent::ParentChange to fix the event filtering in case some dynamic reparenting happens. How bad of a solution is this?

                                      I'd love your feedback on this.

                                      kshegunovK Offline
                                      kshegunovK Offline
                                      kshegunov
                                      Moderators
                                      wrote on last edited by
                                      #26

                                      @ThThoma said in Detect top/parent move event on child widget:

                                      1. The floating widget has a timer and periodically changes itself to follow the placeholder. -> This does not seem like a great idea, if the timer is too fast, we are wasting resources and if the timer is too slow, the user might move the window containing the placeholder, and the delay will be noticeable.

                                      Agreed. This seems like an ugly clutch.

                                      1. The floating widget installs an event filter, not to catch any QEvent::Move, but to catch QEvent::WindowActivate that all the child widgets receive after a move is complete (please correct me if this is not the case). There will be a delay, yes, until the user completes the window movement but for now acceptable (cheaper than timer). -> Problem? What if the placeholder is placed inside a widget that is scrollable (QScrollArea::setWidget())? It won't receive QEvent::WindowActivate, but the placeholder parent widget (the widget inside the QScrollArea) will actually move! And this leads me to:

                                      Eh, I'm not sure you're guaranteed to get that event, it may be platform specific.

                                      1. The floating widget installs an event filter to the whole parent hierarchy, to catch the actual QEvent::Move . Starting from the placeholder and going up on parentWidget() until we find nullptr we install an eventFilter listening on QEvent::Move and probably to QEvent::ParentChange to fix the event filtering in case some dynamic reparenting happens. How bad of a solution is this?

                                      Almost what I get off the top of my head. You can still keep the pointer to the placeholder, but on "attachment" you traverse the object hierarchy up until you get a widget that has the Qt::Window flag set (i.e. it's a top-level window). Then you install the event filter on that widget. Bear in mind that if the placeholder changes ancestry, you may need to respond to the appropriate event and remove the event filter from the old object, and install it to the new top-level window.

                                      Read and abide by the Qt Code of Conduct

                                      T 1 Reply Last reply
                                      2
                                      • kshegunovK kshegunov

                                        @ThThoma said in Detect top/parent move event on child widget:

                                        1. The floating widget has a timer and periodically changes itself to follow the placeholder. -> This does not seem like a great idea, if the timer is too fast, we are wasting resources and if the timer is too slow, the user might move the window containing the placeholder, and the delay will be noticeable.

                                        Agreed. This seems like an ugly clutch.

                                        1. The floating widget installs an event filter, not to catch any QEvent::Move, but to catch QEvent::WindowActivate that all the child widgets receive after a move is complete (please correct me if this is not the case). There will be a delay, yes, until the user completes the window movement but for now acceptable (cheaper than timer). -> Problem? What if the placeholder is placed inside a widget that is scrollable (QScrollArea::setWidget())? It won't receive QEvent::WindowActivate, but the placeholder parent widget (the widget inside the QScrollArea) will actually move! And this leads me to:

                                        Eh, I'm not sure you're guaranteed to get that event, it may be platform specific.

                                        1. The floating widget installs an event filter to the whole parent hierarchy, to catch the actual QEvent::Move . Starting from the placeholder and going up on parentWidget() until we find nullptr we install an eventFilter listening on QEvent::Move and probably to QEvent::ParentChange to fix the event filtering in case some dynamic reparenting happens. How bad of a solution is this?

                                        Almost what I get off the top of my head. You can still keep the pointer to the placeholder, but on "attachment" you traverse the object hierarchy up until you get a widget that has the Qt::Window flag set (i.e. it's a top-level window). Then you install the event filter on that widget. Bear in mind that if the placeholder changes ancestry, you may need to respond to the appropriate event and remove the event filter from the old object, and install it to the new top-level window.

                                        T Offline
                                        T Offline
                                        ThThoma
                                        wrote on last edited by
                                        #27

                                        Thanks @kshegunov ,

                                        so what I get is, that its 'ok' to install an event filter to a Qt::Window parent to track the move events and move a floating widget accordingly.

                                        • However, what if I have multiple floating widgets that track their "parent" movements?

                                        And I'm answering: probably the delay from the multiple filters will start to get noticeable...

                                        Anyhow, this whole search about "floating widgets that detect parent move events" made me understand move events better and that any solution that requires such floating widgets, will probably add some delay and extra logic/conditions to ensure no weird re-parenting behavior.

                                        Cheers again!

                                        kshegunovK 1 Reply Last reply
                                        0
                                        • T ThThoma

                                          Thanks @kshegunov ,

                                          so what I get is, that its 'ok' to install an event filter to a Qt::Window parent to track the move events and move a floating widget accordingly.

                                          • However, what if I have multiple floating widgets that track their "parent" movements?

                                          And I'm answering: probably the delay from the multiple filters will start to get noticeable...

                                          Anyhow, this whole search about "floating widgets that detect parent move events" made me understand move events better and that any solution that requires such floating widgets, will probably add some delay and extra logic/conditions to ensure no weird re-parenting behavior.

                                          Cheers again!

                                          kshegunovK Offline
                                          kshegunovK Offline
                                          kshegunov
                                          Moderators
                                          wrote on last edited by
                                          #28

                                          @ThThoma said in Detect top/parent move event on child widget:

                                          However, what if I have multiple floating widgets that track their "parent" movements?

                                          You'd have multiple event filters.

                                          And I'm answering: probably the delay from the multiple filters will start to get noticeable...

                                          I really doubt it, as long as you don't have too many. If you keep the event processing responsive, you shouldn't notice it at all. Personally, I'd rather have the window in a layout, or if it's really floating, then leave it be, but ymmv.

                                          Read and abide by the Qt Code of Conduct

                                          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