Results 1 to 3 of 3

Thread: Custom QTabBar issue when movable

Hybrid View

Previous Post Previous Post   Next Post Next Post
  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 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
  •  
Qt is a trademark of The Qt Company.