Results 1 to 7 of 7

Thread: dock title bar crash on close

  1. #1
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default dock title bar crash on close

    Hi all,
    I have a dock widget custom class who use a custom titlebar.
    All works fine but when I close the application and one dock is floating, I have a crash.
    Without the custom titlebar I have 0 crash, I tried to find but all looks fine to me.
    Code :
    Qt Code:
    1. CDockWidget::CDockWidget( const QString& Title, QWidget* Parent ) :
    2. QDockWidget( Title, Parent )
    3. {
    4. m_Titlebar = new CTitlebarWidget( this );
    5. setTitleBarWidget( m_Titlebar );
    6. installEventFilter( this );
    7. }
    8.  
    9. bool CDockWidget::eventFilter( QObject* watched, QEvent* event )
    10. {
    11. switch( event->type() )
    12. {
    13. case QEvent::WindowTitleChange :
    14. {
    15. m_Titlebar->SetTitle( windowTitle() );
    16. return true;
    17. }
    18.  
    19. case QEvent::NonClientAreaMouseButtonDblClick :
    20. {
    21. if( isMaximized() )
    22. showNormal();
    23. else
    24. showMaximized();
    25. return true;
    26. }
    27. }
    28. return false;
    29. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. CTitlebarWidget::CTitlebarWidget( QWidget* Parent ) :
    2. QFrame( Parent )
    3. {
    4. // Set the object name.
    5. setObjectName( "Titlebar" );
    6.  
    7. // Connect the dock signal when the floating state change.
    8. connect( Parent, SIGNAL( topLevelChanged( bool ) ), this, SLOT( ChangeFloatingState( bool ) ) );
    9.  
    10. // Create the title label.
    11. m_TitleLabel = new QLabel( Parent->windowTitle() );
    12. m_TitleLabel->setObjectName( "TitlebarLabel" );
    13.  
    14. // Minimize button.
    15. m_MinimizeButton = new QToolButton;
    16. m_MinimizeButton->setObjectName( "TitlebarMinimizeButton" );
    17. connect( m_MinimizeButton, SIGNAL( clicked() ), this, SLOT( MinimizeButton() ) );
    18.  
    19. // Maximize button.
    20. m_MaximizeButton = new QToolButton;
    21. m_MaximizeButton->setObjectName( "TitlebarMaximizeButton" );
    22. connect( m_MaximizeButton, SIGNAL( clicked() ), this, SLOT( ChangeParentMaximizeState() ) );
    23.  
    24. // Float button.
    25. m_FloatButton = new QToolButton;
    26. m_FloatButton->setObjectName( "TitlebarFloatButton" );
    27. connect( m_FloatButton, SIGNAL( clicked() ), this, SLOT( FloatButton() ) );
    28.  
    29. // Close button.
    30. m_CloseButton = new QToolButton;
    31. m_CloseButton->setObjectName( "TitlebarCloseButton" );
    32. connect( m_CloseButton, SIGNAL( clicked() ), Parent, SLOT( close() ) );
    33.  
    34. // Create the control layout.
    35. QHBoxLayout* ControlLayout = new QHBoxLayout;
    36. ControlLayout->setMargin( 0 );
    37. ControlLayout->setSpacing( 0 );
    38. ControlLayout->addWidget( m_MinimizeButton );
    39. ControlLayout->addWidget( m_MaximizeButton );
    40. ControlLayout->addWidget( m_FloatButton );
    41. ControlLayout->addWidget( m_CloseButton );
    42.  
    43. // Set the floating state.
    44. CDockWidget* ParentDock = static_cast< CDockWidget* >( Parent );
    45. ChangeFloatingState( ParentDock->isFloating() );
    46.  
    47. // Create the layout.
    48. QHBoxLayout* Layout = new QHBoxLayout;
    49. Layout->setMargin( 4 );
    50. Layout->addWidget( m_TitleLabel );
    51. Layout->addLayout( ControlLayout );
    52.  
    53. // Set the layout.
    54. setLayout( Layout );
    55. }
    56.  
    57. void CTitlebarWidget::SetTitle( const QString& Title )
    58. {
    59. m_TitleLabel->setText( Title );
    60. }
    61.  
    62. QString CTitlebarWidget::GetTitle() const
    63. {
    64. return m_TitleLabel->text();
    65. }
    66.  
    67. void CTitlebarWidget::mouseDoubleClickEvent( QMouseEvent* event )
    68. {
    69. ChangeParentMaximizeState();
    70. }
    71.  
    72. void CTitlebarWidget::mouseMoveEvent( QMouseEvent* event )
    73. {
    74. // Base class.
    75. QFrame::mouseMoveEvent( event );
    76.  
    77. // Check if we move with the left button.
    78. if( event->buttons() == Qt::MouseButton::LeftButton )
    79. {
    80. // Cast the parent.
    81. CDockWidget* Parent = static_cast< CDockWidget* >( parent() );
    82.  
    83. // Change parent state.
    84. if( Parent->isMaximized() )
    85. Parent->showNormal();
    86. }
    87. }
    88.  
    89. void CTitlebarWidget::MinimizeButton()
    90. {
    91. CDockWidget* Parent = static_cast< CDockWidget* >( parent() );
    92. Parent->setFloating( false );
    93. }
    94.  
    95. void CTitlebarWidget::FloatButton()
    96. {
    97. CDockWidget* Parent = static_cast< CDockWidget* >( parent() );
    98. Parent->setFloating( true );
    99. }
    100.  
    101. void CTitlebarWidget::ChangeParentMaximizeState()
    102. {
    103. // Cast the parent.
    104. CDockWidget* Parent = static_cast< CDockWidget* >( parent() );
    105.  
    106. // Change parent state.
    107. if( Parent->isMaximized() )
    108. Parent->showNormal();
    109. else
    110. Parent->showMaximized();
    111. }
    112.  
    113. void CTitlebarWidget::ChangeFloatingState( bool Floating )
    114. {
    115. if( Floating )
    116. {
    117. m_MinimizeButton->setVisible( true );
    118. m_MaximizeButton->setVisible( true );
    119. m_FloatButton->setVisible( false );
    120. }
    121. else
    122. {
    123. m_MinimizeButton->setVisible( false );
    124. m_MaximizeButton->setVisible( false );
    125. m_FloatButton->setVisible( true );
    126. }
    127. }
    To copy to clipboard, switch view to plain text mode 
    Is it a possible bug of Qt ?
    Thanks

  2. #2
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: dock title bar crash on close

    What's the stack trace when you get the crash?
    Could m_Titlebar be invalid in the even filter?

    Cheers,
    _

    P.S.: instead of installing an event filter on yourself, how about implementing the event() method?
    Should be the same result but much cleaner code wise.

  3. #3
    Join Date
    Apr 2012
    Posts
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: dock title bar crash on close

    you can debug your program with the stacktrace .
    A probable reason is violence memory access

  4. #4
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: dock title bar crash on close

    Quote Originally Posted by anda_skoa View Post
    What's the stack trace when you get the crash?
    P.S.: instead of installing an event filter on yourself, how about implementing the event() method?
    Should be the same result but much cleaner code wise.
    Thanks for the tip, I changed to :
    Qt Code:
    1. bool CDockWidget::event( QEvent* event )
    2. {
    3. switch( event->type() )
    4. {
    5. case QEvent::WindowTitleChange :
    6. {
    7. m_Titlebar->SetTitle( windowTitle() );
    8. return true;
    9. }
    10.  
    11. case QEvent::NonClientAreaMouseButtonDblClick :
    12. {
    13. if( isMaximized() )
    14. showNormal();
    15. else
    16. showMaximized();
    17. return true;
    18. }
    19. }
    20. return QDockWidget::event( event );
    21. }
    To copy to clipboard, switch view to plain text mode 
    I still searching where the crash is from, maybe something missing in the custom QDockWidget.
    Last edited by Alundra; 26th May 2014 at 18:23.

  5. #5
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: dock title bar crash on close

    I have found the crash, it's here :
    Qt Code:
    1. void CMainEditorWindow::closeEvent( QCloseEvent* event )
    2. {
    3. DE::CEngine::Shutdown();
    4. SDL_Quit();
    5. }
    To copy to clipboard, switch view to plain text mode 
    Apparently it's because I use a QTimer to refresh my central widget who is a 3D render.
    When the application close, manager clear data but the render is called who should not.
    Is it a way to avoid this problem ? Maybe a way to know the app is closing ?
    Here the code of the widget who call the QTimer :
    Qt Code:
    1. IRenderWidget::IRenderWidget( QWidget* Parent ) :
    2. QWidget( Parent ),
    3. m_Initialized( false ),
    4. m_RenderWindow( NULL )
    5. {
    6. // Initialize the widget.
    7. setMinimumSize( 320, 240 );
    8. setAttribute( Qt::WA_PaintOnScreen );
    9. setAttribute( Qt::WA_OpaquePaintEvent );
    10. setAttribute( Qt::WA_NoSystemBackground );
    11. setFocusPolicy( Qt::StrongFocus );
    12. setMouseTracking( true );
    13.  
    14. // Set the timer interval.
    15. m_Timer.setInterval( static_cast< int >( (1.0f / 60.0f) * 1000.0f ) );
    16. }
    To copy to clipboard, switch view to plain text mode 
    Thanks

    EDIT: I have found a solution, say me if it's the only one possible :
    Qt Code:
    1. void IRenderWidget::closeEvent( QCloseEvent* event )
    2. {
    3. disconnect( &m_Timer, SIGNAL( timeout() ), this, SLOT( UpdateOneFrame() ) );
    4. }
    5.  
    6. void CMainEditorWindow::closeEvent( QCloseEvent* event )
    7. {
    8. centralWidget()->close();
    9. DE::CEngine::Shutdown();
    10. SDL_Quit();
    11. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Alundra; 26th May 2014 at 20:31.

  6. #6
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: dock title bar crash on close

    I still searching where the crash is from, maybe something missing in the custom QDockWidget.
    Learn how to use a debugger. As others have suggested, the stack trace will tell you exactly where the crash occurs.

    Edit -- I see our posts crossed... this is what I originally said:

    I would not be surprised to find that it is this line:

    Qt Code:
    1. CDockWidget* Parent = static_cast< CDockWidget* >( parent() );
    To copy to clipboard, switch view to plain text mode 

    How do you know that parent() returns a CDockWidget? You don't check, you just assume that the static_cast<> returns a pointer to one. QDockWidget might have several layers of widgets between itself and its contents to help with layout (like QFrame, QAbstractScrollArea, and so forth). Better code is:

    Qt Code:
    1. CDockWidget* pParent = qobject_cast< CDockWidget* >( parent() );
    2. if ( pParent )
    3. {
    4. // Non-null, so it really is a CDockWidget and it is safe to do something with it
    5. }
    To copy to clipboard, switch view to plain text mode 

    To answer your other question:

    Qt Code:
    1. void IRenderWidget::closeEvent( QCloseEvent* event )
    2. {
    3. disconnect( &m_Timer, SIGNAL( timeout() ), this, SLOT( UpdateOneFrame() ) );
    4. }
    To copy to clipboard, switch view to plain text mode 

    Can't you just call QTimer::stop() instead? "mTimer" looks like it is a member variable in your IRenderWidget class, so it will be disconnected and destroyed when the IRenderWidget instance is destroyed.
    Last edited by d_stranz; 26th May 2014 at 20:40.

  7. #7
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: dock title bar crash on close

    Learn how to use a debugger.
    I saw it, but sounded too weird to me, couldn't believe it.
    How do you know that parent() returns a CDockWidget?
    Because CTitleBarWidget is always on a CDockWidget, it's the custom titlebar widget.
    Can't you just call QTimer::stop() instead? "mTimer" looks like it is a member variable in your IRenderWidget class, so it will be disconnected and destroyed when the IRenderWidget instance is destroyed.
    The problem is this render widget is central widget and if I don't do that I have the crash, I must stop myself ...
    Image to show you how it is : http://uppix.com/f-DreamEditor1453839b9d00168cf5.png.
    It's weird that I only had crash when floating, but the leak was always there.

Similar Threads

  1. Replies: 1
    Last Post: 27th October 2015, 18:32
  2. Replies: 1
    Last Post: 18th July 2012, 14:33
  3. midi child does not close when I call close()
    By qlands in forum Qt Programming
    Replies: 7
    Last Post: 29th July 2011, 22:25
  4. forcing dock windows to dock?
    By eric_vi in forum Qt Programming
    Replies: 3
    Last Post: 9th August 2009, 15:32
  5. Replies: 5
    Last Post: 21st April 2008, 07:54

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.