[Solved] Make a popup stick to a widget to move them simultaneously



  • I have a somewhat complex window containing a small widget and I am showing a semi-persistent popup for that widget (Qt::Window | Qt::FramelessWindowHint | Qt::CustomizeWindowHint). When I now move the whole window, the popup does not move along. Does anybody have an idea how to make the popup stick to its widget?

    I would greatly appreciate any input. :)


  • Lifetime Qt Champion

    Hi,

    Just an idea but you could subclass the moveEvent of your "main window" and move the popup using the old and new coordinates

    Hope it helps



  • [quote author="SGaist" date="1393964188"]Hi,

    Just an idea but you could subclass the moveEvent of your "main window" and move the popup using the old and new coordinates

    Hope it helps[/quote]

    I have used this method to implement a heads-up display. It's nice as it allows you to continue building your interface with Designer as opposed to building it with graphics, but I would ensure this is the behavior you actually want. When you design a pop-up to keep a static relative position, it's often worth considering a more natively supported method like a docked window. Best of luck!



  • The moveEvent() doesn't seem to be an option. The hierarchy is complicated, and only the topmost widget receives the moveEvent. Inside that one there are some specialized widgets which consist of specialized widgets, etc. So the "grand-grand-parent" does not have easy access to the popup.
    That's why I mentioned the "small widget" inside the complex window.



  • Do all of the specialized widgets need to move as well, or just the one popup? Could you give us some further info as to the behavior your trying to bring about, or further info on what's happening in your app? Perhaps a more robust solution could be proposed. With what I'm envisioning currently, the handling could get very tricky and become bug-prone.



  • If the window moves, the specialized widgets move, too (normal window behavior). They are part of the window. The popup, however, belongs to one of the "grand-grand-children" widgets, so it's movement is not tied to the window itself. And the only widget it knows about does not receive any moveEvents.

    The behavior is the following: A QLineEdit may contain a lot of text. For the rare occasion where it is filled up, an in-place popup QLineEdit opens, able to grow with its content, not restricted by the windows boundary. Opening the popup is seamless and I considered it a nice idea.

    The behavior so far is very satisfying, but while the user moves the window (popup is opened), the popup stays in place. Once the window is done being moved around, the popup snaps back into its place.

    Since the window is very modular, I don't see a way to easily make the top-level window and the popup communicate.



  • Capture MainWindow position and your popup widget position.
    widget->mapToGlobal( widget->pos() );
    You can get a relative offset which I assume is fixed...

    Could it then be possible if you emit a signal from the top level window on a MoveEvent. Write a handler(slot) to this signal in your popup widget.
    Once that is invoked recalculate the above and calculate the translation of MainWindow. Based on that translate the popup Widget.

    Just a thought.



  • Sounds like an interesting and unique way to handle this situation.

    [quote author="prady_80" date="1394044779"]Capture MainWindow
    Could it then be possible if you emit a signal from the top level window on a MoveEvent. Write a handler(slot) to this signal in your popup widget.
    Once that is invoked recalculate the above and calculate the translation of MainWindow. Based on that translate the popup Widget.
    [/quote]

    I would second this route. Using the signal would allow you that link between the main window and you window. However, be careful of what might happen if the user enters a ton of text; so much text that it could run off your window (if your popup is allowed to continue growing).

    Best of luck.



  • The popup isn't allowed to grow beyond the screens size.

    Concerning the idea using a signal: Is it common practice to hand a signal through a couple of widgets to get it where it is needed? That always feels a bit strange to me.

    Are signals even processed while a widget is being moved?



  • It depends on the architecture of your software. In some cases, it may be good design to propagate the signal in this way. I personally wouldn't say it's common practice to do it manually, though, and it can get quite "strange" as you say, but propagation of events is very common throughout Qt and the MVC paradigm in general.

    As for the signals themselves, you are correct, they will still be processed as you move the window.



  • "According to the documentation":http://qt-project.org/doc/qt-5/qwidget.html#moveEvent, the moveEvent() should not be usable to track the movement of a window:
    "When the widget receives this event, it is already at the new position."

    Hence, using it would result in the same behavior I already have (the popup snapping into position after the window has been moved).

    What does make child-widgets move along with its parent? It's not the layout. Could I maybe make the popup behave as some kind of "floating child", so Qt handles its movement with no extra work needed by me?



  • I'm not sure the documentation is fully clear here. As with the "resizeEvent":http://qt-project.org/doc/qt-4.8/qwidget.html#resizeEvent, even though it receives the event after the geometry has already changed, the widget will receive the event every time the system has picked up that the window has changed. That is, not just a single, final position. In "this link":http://stackoverflow.com/questions/18385916/how-to-keep-a-qwidget-or-qdialog-centered-to-its-parent-widget someone is doing similar to what you are looking for.



  • Thanks a lot! Even though handing a signal through several classes (each of them now needs an additional signal itself) feels a bit cumbersome and inelegant, I went with it and everything works perfectly fine now. Had to put some more work into placing the cursor within the popup QLineEdit, but the result is satisfying and fun to use. :)

    Still I would be interested to know: "Who" or "what" does move the window eventually? This mysterious thing looks at the window and its popup as different entities, so when moving the window really fast there is a slight stutter visible. I assume it would be possible to somehow "hard-link" the two objects to make them move as one...but that for sure is either part of some private class of Qt or even of the operating system. If anybody knows, tell me!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.