Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QDockWidget resize issue



  • Hi,
    My application is basically a QMainWindow class with several QDockWidget objects around. Right now, I am dealing with this annoying issue:

    • When I open my app and I try to resize any of the QDockWidget objects, they always recover their initial dimension. It doesn't matter if I try to make them bigger or smaller, the size of every dock seems to be fixed.
      Now, if I drag one of the docks until it starts to float over the main window and I put it back to its initial position, then, the fixed-size restriction is disabled and I can resize any of the docks as I want to.
      I made this little video showing the issue: https://www.youtube.com/watch?v=8FDs_D-lLuU

    Question: How can I disable the fixed-size restriction from the beginning? What happens when the dock is floating? Why the restriction disappears after that event? I didn't code that behavior.

    Any hint is very welcome! :)


  • Lifetime Qt Champion

    Hi,

    Are you deleting these docks each time ?



  • @SGaist No. In fact, the QDockWidget objects are created at the beginning of the program and only destroyed when the user quits the app.

    Questions:

    1. Which element is in charge of enabling the feature of resizing a QDockWidget object using the mouse? Is the Dock itself? Or is the QWidget inside the Dock?
    2. Is the feature of resizing the Dock based on a size policy (QSizePolicy)?
    3. Is the free resizing feature of a Dock enabled by default or do I have to activate it by myself?

    Note: I was checking my code and I am not calling any setFixedSize() method or any kind of restraint action related to the widgets dimension.



  • I'm having the same problem. Has anyone found an answer to this?


  • Lifetime Qt Champion

    Hi
    I cannot seem to reproduce this with any of the Docks samples.
    So I assume its related to the widget you put inside and its sizeing
    options.



  • @mrjj Those files are part of my project's source code. I really appreciate if you can help me taking a look at them; maybe you can see something that I don't:

    I have been looking for setSizePolicy/setFixedSize/etc instructions or something related to the size behavior of the widgets, but I can't find anything yet.


  • Moderators

    @xtingray I've never seen anything like this before, I would focus on what your QMainWindow is doing, check you are not interfering with its layout at all, if you are just using addDockWidget and setCentralWidget then you should be on safe ground. Otherwise without a small example its hard to say what is causing this. Are you using restoreState/restoreGeometry at all too?



  • @AndyS After several days in this "witch hunt" inspecting all my source files, finally I found the method where the problem comes from.
    The funny thing is that it isn't related neither to the QMainWindow class or the QDockWidget objects. It's about a QGraphicsView subclass component that I included inside the central widget of my app.

    This is the method that generates the automatic resizing action of all the expanded docks every time the mouse cursor moves over the QGraphicsView area, as you can see it in the video at the first post:

    bool TupPaintAreaBase::viewportEvent(QEvent *event)
    {
        return QGraphicsView::viewportEvent(event);
    }
    

    If I just return "true" from this method, then I lost all the painting events of my app, but I can resize freely all the docks from the main window as it should be.
    If I remove this method from my class, the problem occurs anyway.

    Now, the big question: what should I do to avoid this behavior? what is best way to deal with this problem?

    Thank you for any hint!


  • Moderators

    @xtingray I find it odd that it depends on that at all so I would need a small example to see the behavior first hand really. I suspect a problem in the code, but I don't know where to start in this case. It seems that the QGraphicsView is getting events it shouldn't be, as a guess, try returning true just for QEvent::Resize and see if that makes a difference. If it does then I would put a breakpoint there to see where the resize events are coming from.



  • @AndyS Following the signal emitted when the mouse pointer enters over the QGraphicsView area I could discover the real cause of the problem.

    The method QGraphicsView::viewportEvent( ) was a tricky but handy place to trace the focus of the real problem:
    At the bottom side of the workspace, there is a panel with several icons and controls. Every time the mouse pointer moves over the QGraphicsView area, some of the elements (i.e. QLabel items) at the bottom panel are updated by several slots. That "re-paint" action activates the resize event of the whole central widget. I still don't get why but it happens.

    The class related to that panel is defined right here:
    https://github.com/xtingray/tupitube.desk/blob/devel/src/components/workspace/tuppaintareastatus.cpp

    If I disable the specific signal that updates the panel, then the resize action never occurs and everything is all right.
    I wonder if I have to take out that bottom panel from the central widget to solve the problem or if there is a better way to fix this issue. Suggestions?


  • Moderators

    @xtingray Based on this at least I can't see why it would cause a problem, but just seeing this code isn't enough to really dig into the problem. If you have a workaround then I would go for it, otherwise you need to cut the code down to show the problem so that it is easier for us to look at it directly.



  • @AndyS I will try to show you the more relevant parts of the code related to the problem. As the interface is complex enough, it's not so easy to explain the workflow of the components, but I will try to do my best:

    1. The main window of my app is a QMainWindow object. The central widget of that window is another QMainWidow object, a subclass called TupDocumentView.
      This is the more relevant part of that code for this thread:
    TupDocumentView::TupDocumentView(QWidget  *widget) : QMainWindow(parent)
    {
      k->paintArea = new TupPaintArea(project); // QGraphicsView subclass
      connect(k->paintArea, SIGNAL(cursorPosition(const QPointF &)), this, SLOT(showPos(const QPointF &))); 
      // If the mouse pointer moves over the QGraphicsView area, 
      // a label at the QStatusBar object  is updated
    
      QWidget *workspace = new QWidget;
      QGridLayout *layout = new QGridLayout(workspace);
      layout->addWidget(k->paintArea, 0, 0);
    
      k->status = new TupPaintAreaStatus(contourPen(), fillBrush()); // QStatusBar subclass
      setStatusBar(k->status);
    }
    
    void TupDocumentView::showPos(const QPointF &point)
    {
      QPoint dot = point.toPoint();
      QString message =  "X: " +  QString::number(dot.x()) + " Y: " + QString::number(dot.y());
      k->status->updatePosition(message); 
      // The status bar is updated with the mouse pointer new position
    }
    
    1. TupPaintAreaStatus is a QStatusBar subclass. As part of its public slots, there is one in charge of updating the mouse position label:
    void TupPaintAreaStatus::updatePosition(const QString &pos)
    {
        k->positionLabel->setText(pos);
    }
    
    1. Every time I move the mouse pointer over the QGraphicsView area , the signal cursorPosition() is sent to the central widget (TupDocumentView). There, the slot showPos(const QPointF &point) is executed, calling the method updatePosition() from the status bar (TupPaintAreaStatus). With this implementation I always can display the current position of the mouse. That part works perfectly.

    2. There is a collateral effect when the status bar element (QLabel) is updated: the entire central widget (TupDocumentView) is always resized when the mouse pointer moves over the QGrahpicsView area. Note: For a better understanding of this problem, please watch the video at the first post.
      But, If I comment this line from the TupPaintAreaStatus class:

    k->positionLabel->setText(pos);
    

    Then, the central widget auto-resizing action disappears. This is just a way to show where the problem is generated. Now, I need to update several controls from the status bar but avoiding the central widget resizing behavior, how can I do it?


  • Lifetime Qt Champion

    Hi so if you are 100% positively sure its
    k->positionLabel->setText(pos);
    that does makes it go strange, you could
    try a small custom class that just draws text to
    see if that avoid this resize issue.

    From video it seems something is insisting on a certain size
    preventing resize.



  • @mrjj Looking for options to replace the QLabel element I tried two approaches that are working a lot better:

    1. I replaced the QLabel variable by a QLineEdit object . The resizing action only occurs one or two times, after that I can resize any dock freely.

    2. Understanding that I am using a QStatusBar subclass, I replaced the QLabel object by the method showMessage(QString). Same thing, the resizing action occurs a couple of times and then, the size restriction is disabled.

    For now, this workaround enhances the user experience of my app, but it's not a definitive solution.
    Any way, in case you want to reproduce my problem in a very basic way, you just have to do this:

    • Create a QMainWindow object as your main component Add a couple of QDockWidget items to that window.
    • Create another QMainWindow object as the central widget of your main component
    • Create a QGraphicsView object and a QStatusBar as part of the inner QMainWindow you set as your central widget. Include a QLabel object as part of your QStatusBar component.
    • Emit a signal from the QGraphicsView object every time the mouse pointer moves over that component. That signal must activate a slot from the inner QMainWindow to update the QLabel inside the QStatusBar (with the new position of the mouse cursor or whatever you want to show).
    • If it is possible to reproduce my bug, then when you try to resize the QDockWidget elements from your external main window, both of them will recover its initial size, as if some "setFixedSize" policy had been set.

    Any way, if I found a better solution for this bug, I will let you know.



  • @xtingray Hi, It may be related to this bug : https://bugreports.qt.io/browse/QTBUG-65592
    Se this post



  • @Gojir4 Amazing! Just one line and the problem disappears!

        addDockWidget(area, toolView);
        resizeDocks({toolView}, {0}, Qt::Horizontal); // This is the hack
    

    I spent about three weeks looking for a fix for this annoying problem, thinking "it's something I am doing wrong" XD

    Obviously this is a hack but it works! :P


Log in to reply