Results 1 to 3 of 3

Thread: Custom QTabBar issue when movable

  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 Custom QTabBar issue when movable

    Hi,
    I have a custom QMainWindow with a QTabBar as center widget, this is basically a tabbed window to have multiple QMainWindow inside.
    All works correctly but I have to disable the move on tab because if I enable it it gives weird behavior when I remove one tab during the move.
    Basically I stay clicked on one tab and if the cursor is outside the QTabBar then the tab is removed and the QMainWindow is then floating.
    The issue is the mouse button is not released so sometimes another tab continue to move, nothing should move anymore.
    I tried all way to disable the move when I remove one tab but no way found.. surely it absolutely wait mouse release event..
    The only way I think of is to write a custom move of tab and manage all myself.
    Is it possible to do it ? Or one hack possible ?
    Maybe a miss in QTabBar code, needs to check if the current pressed is the removed tab, maybe not safe on this case ?

    Another thing is I would know if it's possible to enable the move of the tab.
    example : I remove tab, the window is floating, I tab again
    On this situation the tab should move, the mouse button is not released.
    Only way is to simulate a click event ?

    Thanks
    Last edited by Alundra; 4th January 2018 at 13:43.

  2. #2
    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: Custom QTabBar issue when movable

    I'm sorry, my magic crystal ball that allows me to see invisible code is not working today. If it was working, I might be able to look at your code and give you an idea about what was wrong.

    Maybe someone else has a better crystal ball and can help you out.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    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: Custom QTabBar issue when movable

    Here the code of the tab bar which inherit QTabBar.
    It handle the move of the full window when you click not on a tab and handle when a tab is moved outside the tab bar.
    When a tab is moved outside a tab bar the tab is removed and the QMainWindow widget is now floating.
    Basically the same behavior like web browser for tabs.

    The two issues without any luck finding a solution yet :
    1) When the tab is removed if the tab widget is set to movable, remove tab is called but another tab is then moving during the QMainWindow is moving.
    The moving should be disabled for all tabs and the animation of the tab bar should just be played to set the tab correctly placed.
    Maybe a bug of QTabWidget which doesn't handle the remove tab correctly when it's moving, he waits a release mouse button.

    2) When a tab is put in another or the same tab widget during the move when the QMainWindow is floating, the tab is not moving.
    The user has to release the mouse button and click on the tab, the tab should be moving because the mouse button is not released.

    Thank you for the help
    Qt Code:
    1. class CTabbedWindowTabWidget : public QTabWidget
    2. {
    3. public:
    4.  
    5. CTabbedWindowTabWidget( QWidget* Parent = nullptr ) :
    6. QTabWidget( Parent )
    7. {
    8. setTabBar( new CTabbedWindowTabBar( this ) );
    9. }
    10. };
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. CTabbedWindowTabBar::CTabbedWindowTabBar( QWidget* Parent ) :
    2. QTabBar( Parent ),
    3. m_DragWindow( nullptr ),
    4. m_IsDraggingTab( false ),
    5. m_IsDraggingWindow( false )
    6. {
    7. }
    8.  
    9. void CTabbedWindowTabBar::mouseMoveEvent( QMouseEvent* event )
    10. {
    11. // Base class.
    12. QTabBar::mouseMoveEvent( event );
    13.  
    14. // Check the dragging window state.
    15. if( m_IsDraggingWindow )
    16. {
    17. // Get the window.
    18. CTabbedWindow* TabbedWindow = static_cast< CTabbedWindow* >( parent()->parent()->parent() );
    19.  
    20. // Move the window is only possible if the window is not maximized.
    21. if( TabbedWindow->isMaximized() )
    22. TabbedWindow->showNormal();
    23.  
    24. // Move the window using this delta.
    25. TabbedWindow->move( QCursor::pos() - m_DragWindowOffsetPos );
    26.  
    27. // Stop here.
    28. return;
    29. }
    30.  
    31. // Check the dragging tab state.
    32. if( m_IsDraggingTab == false )
    33. return;
    34.  
    35. // Check if the drag window is not valid.
    36. if( m_DragWindow == nullptr )
    37. {
    38. // Test if the mouse is outside the tab bar.
    39. if( rect().contains( event->pos() ) == false )
    40. {
    41. // Get the tab widget.
    42. QTabWidget* TabWidget = static_cast< QTabWidget* >( parent() );
    43.  
    44. // Don't create a new window if the tab bar only has 1 tab.
    45. if( TabWidget->count() == 1 )
    46. {
    47. m_DragWindow = static_cast< CTabbedWindow* >( TabWidget->parent()->parent() );
    48. }
    49. else
    50. {
    51. // Get the main window.
    52. QMainWindow* MainWindow = static_cast< QMainWindow* >( TabWidget->currentWidget() );
    53.  
    54. // Remove the tab.
    55. static_cast< CTabbedWindow* >( TabWidget->parent()->parent() )->RemoveTab( TabWidget->currentIndex() );
    56.  
    57. // Add the tab on the new window.
    58. m_DragWindow = new CTabbedWindow;
    59. m_DragWindow->AddTab( MainWindow );
    60. }
    61.  
    62. // Set the window properties.
    63. m_DragWindow->setWindowOpacity( 0.5 );
    64. m_DragWindow->setAttribute( Qt::WA_TransparentForMouseEvents );
    65.  
    66. // Show and move the window.
    67. m_DragWindow->show();
    68. m_DragWindow->move( event->globalPos() );
    69. }
    70. }
    71. else
    72. {
    73. // Find the tab bar under the mouse.
    74. CTabbedWindowTabBar* TargetTabBar = qobject_cast< CTabbedWindowTabBar* >( QApplication::widgetAt( event->globalPos() ) );
    75.  
    76. // Check if a tab bar is found.
    77. if( TargetTabBar )
    78. {
    79. CTabbedWindow* TargetTabbedWindow = static_cast< CTabbedWindow* >( TargetTabBar->parent()->parent()->parent() );
    80. QMainWindow* MainWindow = m_DragWindow->GetCurrentTabWindow();
    81. m_DragWindow->RemoveTab( m_DragWindow->GetCurrentTab() );
    82. TargetTabbedWindow->AddTab( MainWindow );
    83. m_IsDraggingTab = false;
    84. m_DragWindow = nullptr;
    85. }
    86. else
    87. {
    88. m_DragWindow->move( event->globalPos() );
    89. }
    90. }
    91. }
    92.  
    93. void CTabbedWindowTabBar::mousePressEvent( QMouseEvent* event )
    94. {
    95. // Base class.
    96. QTabBar::mousePressEvent( event );
    97.  
    98. // Actions only possible with the left button.
    99. if( event->button() == Qt::LeftButton )
    100. {
    101. // Get the tab index, -1 is returned if no tab found.
    102. const int TabIndex = tabAt( event->pos() );
    103.  
    104. // Check the widget on each side of the tab.
    105. QWidget* LeftSide = tabButton( TabIndex, QTabBar::LeftSide );
    106. QWidget* RightSide = tabButton( TabIndex, QTabBar::RightSide );
    107.  
    108. // The dragging tab flag is enabled only if one tab is found and if one widget is in the tab.
    109. m_IsDraggingTab = ( TabIndex != -1 ) && ( ( LeftSide != nullptr ) || ( RightSide != nullptr ) );
    110.  
    111. // The dragging window flag is enabled only if it's an empty space.
    112. if( TabIndex == -1 )
    113. {
    114. m_IsDraggingWindow = true;
    115. m_DragWindowOffsetPos = static_cast< CTabbedWindow* >( parent()->parent()->parent() )->mapFromGlobal( QCursor::pos() );
    116. }
    117. else
    118. {
    119. m_IsDraggingWindow = false;
    120. }
    121. }
    122. }
    123.  
    124. void CTabbedWindowTabBar::mouseReleaseEvent( QMouseEvent* event )
    125. {
    126. // Base class.
    127. QTabBar::mouseReleaseEvent( event );
    128.  
    129. // Set the window properties.
    130. if( m_DragWindow != nullptr )
    131. {
    132. m_DragWindow->setWindowOpacity( 1.0 );
    133. m_DragWindow->setAttribute( Qt::WA_TransparentForMouseEvents, false );
    134. }
    135.  
    136. // Reset states.
    137. m_IsDraggingWindow = false;
    138. m_DragWindowOffsetPos = QPoint( 0, 0 );
    139. m_IsDraggingTab = false;
    140. m_DragWindow = nullptr;
    141. }
    142.  
    143. void CTabbedWindowTabBar::mouseDoubleClickEvent( QMouseEvent* event )
    144. {
    145. // Action only valid with the left button.
    146. if( event->button() == Qt::LeftButton )
    147. {
    148. // Check if the double click is on an empty space.
    149. if( tabAt( event->pos() ) == -1 )
    150. {
    151. // Get the window.
    152. CTabbedWindow* TabbedWindow = static_cast< CTabbedWindow* >( parent()->parent()->parent() );
    153.  
    154. // Change the maximize state.
    155. if( TabbedWindow->isMaximized() )
    156. TabbedWindow->showNormal();
    157. else
    158. TabbedWindow->showMaximized();
    159.  
    160. // Accept the event.
    161. event->accept();
    162. }
    163. }
    164. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by Alundra; 18th January 2018 at 14:05.

Similar Threads

  1. Using Custom QTabBar with QTabWidget.
    By tvj4218 in forum Newbie
    Replies: 2
    Last Post: 11th May 2017, 21:57
  2. movable QTabBar or QTabWidget set some tabs fixed
    By fsmoke in forum Qt Programming
    Replies: 1
    Last Post: 22nd November 2014, 01:24
  3. Replies: 0
    Last Post: 14th February 2012, 11:03
  4. Replies: 7
    Last Post: 5th June 2011, 20:12
  5. Cann't move movable items on custom graphics view
    By wojtekw in forum Qt Programming
    Replies: 2
    Last Post: 3rd March 2008, 21:30

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.