Results 1 to 3 of 3

Thread: Problem with customized QTabWidget

  1. #1
    Join Date
    Jan 2014
    Posts
    36
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Problem with customized QTabWidget

    I’m trying to duplicate the functionality of how many other applications handle tabs where the last tab is treated as a special case and is used solely to create new tabs. So when my widget launches it looks like:
    \ Tab 1 /\ + /
    With “Tab 1” set as the current index. Left clicking on the ‘+’ will add a new tab called ”Tab 2”, and sets “Tab 2” as the current index, like so:
    \ Tab 1 /\ Tab 2 /\ + /

    To achieve this, I’ve connected the currentChanged(int index) signal to a slot that checks to see if the current index is the last index, and if so it adds a new tab, and sets the newly created one as current. If any other tab is the current index, the slot does nothing. Here’s the code for the slot:
    Qt Code:
    1. void customTabWidget::slotTabBarClicked(int index)
    2. {
    3. if (index != (count() - 1))
    4. {
    5. // if it's not the last one, we don't need to do anything
    6. return;
    7. }
    8.  
    9. // if it's the last tab, we add a new tab
    10. slotAddTab();
    11. }
    To copy to clipboard, switch view to plain text mode 
    This works great when the user left-clicks on the ‘+’ tab.

    I’ve also added a contextual menu that allows the user to rename or delete a tab by right-clicking one of the tabs. I’m handling that in mousePressEvent(). This functionality should work for all tabs EXCEPT the final tab; the user should never be able to rename or delete the ‘+’ tab, since it’s a special case. In mousePressEvent(), I’m attempting to detect which index the user right-clicked on so that I can put the contextual menu in the right place as well as rename/delete the correct tab. Here’s the code for mousePressEvent:
    Qt Code:
    1. void customTabWidget::mousePressEvent(QMouseEvent *event)
    2. {
    3. QTabWidget::mousePressEvent(event);
    4. if (event->button() == Qt::RightButton)
    5. {
    6. for (int i=0; i < tabBar()->count()-1; i++)
    7. {
    8. QPoint clickPos = mapToGlobal(event->pos());
    9. if (tabBar()->tabRect(i).contains(tabBar()->mapFromGlobal(clickPos)))
    10. {
    11. qDebug("Tab count %d, right click on %d", tabBar()->count(), i);
    12. setCurrentIndex(i);
    13. slotShowContextualMenu(clickPos);
    14. }
    15. }
    16. }
    17. }
    To copy to clipboard, switch view to plain text mode 

    Since there’s no reason to show that contextual menu on the ‘+’ tab, I’d like to disable the right click functionality just on the last tab, which I’m trying to do in the mousePressEvent for loop, by only looping to bar->count() – 1. But the problem I’m having is that the right-click on the ‘+’ tab emits currentChanged(int) BEFORE mousePressEvent() is called, causing creation of a new tab in slotTabBarClicked(). Before the user right clicks, count() is 2, current index is 0, and the ‘+’ is at index 1. Once the user right clicks on the ‘+’ tab, by the time we get to mousePressEvent(), count() is 3, current index is 1, and the ‘+’ tab is at index 2. So the mapping doesn’t work and I end up displaying a contextual menu on the newly created “Tab 2”, even though the user right-clicked on the ‘+’ tab.

    The behavior I want is right-clicking on the ‘+’ tab should do nothing; it shouldn’t add a new tab, it shouldn’t show a contextual menu. Right-clicking on any other tab should bring up the contextual menu. Left-clicking on the '+' tab should add a new tab.

    What am I missing, or how should I be trying to do this? If there was a separate signal for left vs. right clicks, it’d be easy. But I don’t see a way to easily detect in slotTabBarClicked(int) that it was a right-click that caused currentChanged(int) to be emitted, or that that right-click was on the '+' tab and that I shouldn't do anything...

  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: Problem with customized QTabWidget

    Quote Originally Posted by SeanM View Post
    But the problem I’m having is that the right-click on the ‘+’ tab emits currentChanged(int) BEFORE mousePressEvent() is called, causing creation of a new tab in slotTabBarClicked().
    The cause this is most likely that the tab widget is not the actual receiver of the mouse event, its QTabBar child is. So th tab bar reacts to the event first and you see it when it propagates upwards.

    My suggestion would be to access the tab bar and its tab buttons.
    For all tab buttons that you want a context menu, set the same context actions using addAction() and set the button's contextMenuPolicy to ActionsContextMenu.

    You should then only have to react to the actions' triggered() signals.

    Another option you could investigate is to use QTabBar's corner widgets.

    Cheers,
    __

  3. #3
    Join Date
    Jan 2014
    Posts
    36
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Problem with customized QTabWidget

    Ok, I hadn't dug down into the QTabBar class, I'm not sure why I didn't think to do that. I'll poke around in it and see what works best.

Similar Threads

  1. Problem using QTabWidget
    By UchihaMk in forum Qt Programming
    Replies: 8
    Last Post: 7th September 2012, 20:58
  2. Problem with QTabWidget
    By alizadeh91 in forum Qt Programming
    Replies: 3
    Last Post: 6th August 2012, 11:12
  3. QTabWidget problem
    By hnfmr in forum Qt Programming
    Replies: 4
    Last Post: 25th February 2011, 15:10
  4. Problem displaying image on a customized button
    By bhavikdhoot in forum Qt Programming
    Replies: 1
    Last Post: 16th December 2010, 10:48
  5. QTabWidget problem
    By Strongoloid in forum Newbie
    Replies: 2
    Last Post: 10th September 2009, 20:38

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.