Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Floating dock widget container is not destroyed instantly when view is redocked #351

Closed
LucasAudebert opened this issue Sep 8, 2021 · 4 comments

Comments

@LucasAudebert
Copy link

I have summarized the problem in the code below.

#include <QMainWindow>
#include "DockManager.h"

namespace Ui
{
    class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow( QWidget *parent = 0 );
    ~MainWindow();

public slots:
    void doSomething();

private:
    Ui::MainWindow *ui;

    // The main container for docking
    ads::CDockManager *m_DockManager;
};

MainWindow.h

#include "MainWindow.h"
#include "ui_MainWindow.h"

#include <QLabel>
#include <QAction>

#include <chrono>
#include <thread>

MainWindow::MainWindow( QWidget *parent ) :
    QMainWindow( parent ),
    ui( new Ui::MainWindow )
{
    ui->setupUi( this );

    // Create the dock manager. Because the parent parameter is a QMainWindow
    // the dock manager registers itself as the central widget.
    m_DockManager = new ads::CDockManager( this );

    // Add a do something action.
    QAction *doSomethingAction = new QAction( "Do something" );
    ui->menuAction->addAction( doSomethingAction );
    connect( doSomethingAction, SIGNAL( triggered() ), this, SLOT( doSomething() ) );

    // Create example content label - this can be any application specific
    // widget
    QLabel *l = new QLabel();
    l->setWordWrap( true );
    l->setAlignment( Qt::AlignTop | Qt::AlignLeft );
    l->setText( "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. " );

    // Create a dock widget with the title Label 1 and set the created label
    // as the dock widget content
    ads::CDockWidget *DockWidget = new ads::CDockWidget( "Label" );
    DockWidget->setWidget( l );

    // Add the toggleViewAction of the dock widget to the menu to give
    // the user the possibility to show the dock widget if it has been closed
    ui->menuView->addAction( DockWidget->toggleViewAction() );

    // Add the dock widget to the top dock widget area
    m_DockManager->addDockWidget( ads::TopDockWidgetArea, DockWidget );
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::doSomething()
{
    std::chrono::milliseconds timespan( 1 );
    
    for ( int i = 0; i != 2000; ++i )
    {
        std::this_thread::sleep_for( timespan );

        // Take into account the events during the loop.
        qApp->processEvents();
    }
}

MainWindow.cpp

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget"/>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>21</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuView">
    <property name="title">
     <string>View</string>
    </property>
   </widget>
   <widget class="QMenu" name="menuAction">
    <property name="title">
     <string>Action</string>
    </property>
   </widget>
   <addaction name="menuView"/>
   <addaction name="menuAction"/>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

MainWindow.ui

To reproduce the issue:

  • Make the dock widget floating
  • Click on the "do something" action, and immediately re-dock the floating widget within the main window
  • See the floating container remains visible
  • Later the container disappears.

capture

"do something” enters a loop but it processes QApplication events (call to processEvents), so that GUI remains responsive.

After a closer look, it seems that the problem comes from the fact that the floating container is not destroyed manually when the widget is docked.

When the widget is redocked, looks like the floating container is requested to be deleted and this is done later by Qt.

Probably the floating container should be manually destroyed or at least hidden so that it disappears from screen waiting to be cleanly deleted by Qt ?

Thank you in advance

@githubuser0xFFFF
Copy link
Owner

Yes, you are right, the floating widget is deleted with deleteLater() call. Please try to implement your proposal and hide the floating widget immediately.

@LucasAudebert
Copy link
Author

@githubuser0xFFFF I tried to hide the floating widget at the line 1569 of "DockContainerWidget.cpp" but it also hid the docking widget (probably because the contained widget still has the floating widget as parent when I hide it).
Do you have another idea of how to solve this problem ?
Thank you in advance

@githubuser0xFFFF
Copy link
Owner

You should try to avoid blocking the event loop. Your doSomething() implementation is not a good solution. Maybe you can do the things in a different thread.

@LucasAudebert
Copy link
Author

The doSomething() method is juste a simple way to reproduce the bug. We are currently using a thread on our programm. Until now, we never had a problem with this kind of implementation.
I'll look further into it if I can find a solution to fix this problem. I will keep you informed if I find a solution.

githubuser0xFFFF pushed a commit that referenced this issue Oct 1, 2021
luelista pushed a commit to luelista/Qt-Advanced-Docking-System that referenced this issue Mar 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants