Layout each tab in QTabBar



  • Hi guys... if someone of you use OS X, you should know that in Safari, when we open a new tab, each tab has the same width, so if I have only 2 tabs, them width will be the half of the width in the QTabBar... well, I'm trying to do this and I can't find on internet any solution, because the only one I've found is use the style property, and set there the width of each tab... I can do that, but If I resize the application, I'l must recalculate all again...

    my question is if QTabWidget or QTabBar has some kind of property which let me show all tabs without any scroll on the tab bar and at the same time, fix each tab width to be sure that all of them has the same width.

    If you want to see what I'm talking about, you can see Safari or Finder applications on OS X Yosemite or El Capitan and you'll see...

    how can I do that ?? what is the best way to make it ??

    regards



  • If I understand you correctly, I'd try:

    eg:

    MyTabBar::MyTabBar(QWidget *parent) : QTabBar(parent) {
        setExpanding(true); // At least by default.
    }
    
    QSize MyTabBar::tabSizeHint(int index) const {
        QSize size = QTabBar::tabSizeHint(index);
        if (expanding()) {
            // The exact value here probably doesn't matter; since we're expanding anyway, the tabs
            // will presumably all expand in even proportions, as they all have the same width hint.
            size.setWidth(1);
        }
        return size;
    }
    
    MyTabWidget::MyTabWidget(QWidget *parent) : QTabWidget(parent) {
        setTabBar(new MyTabBar);
    }
    

    Of course, there may be a simpler way, but that's what I'd try experimenting with if no-one suggests anything nicer :)

    Cheers.



  • Hi Paul and thank you for your answer.

    That doesn't work for me. :(

    In 1st place, the value of QTabBar::tabSizeHint(index) when I call is the value of the widget but without apply its layout. Layout is apply after start event loop until i know, so, at this point, the widget has its initials values for width and height. I didn't see any signal to know if the we are finish to render the widget, to know if i can update the value of the width of the tabs... and I that's the idea, i have to do the same every time when I resize the windows. Am I wrong ?

    I'm going to share the example what I'm testing

    That is the mainwindos.h file

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QTabWidget>
    #include <QTabBar>
    #include <QDebug>
    
    class TabBar : public QTabBar
    {
        Q_OBJECT
    public:
        double _width;
        TabBar(QWidget* parent = nullptr) : QTabBar(parent){
            setExpanding(true);
        }
        virtual QSize tabSizeHint(int index) const {
            Q_UNUSED(index);
            QSize mySyze = QTabBar::tabSizeHint(index);
            qDebug() << "width: " << mySyze.width() << "height: " << mySyze.height() << " count: " << count();
            return QSize(mySyze.width() / count(), mySyze.height());
        }
    };
    
    class MyTabWidget : public QTabWidget
    {
        Q_OBJECT
    public:
        MyTabWidget(QWidget* parent = nullptr):QTabWidget(parent){
    
        }
    
        virtual void setMyTabBar(QTabBar* tabBar){
            setTabBar(tabBar);
        }
        virtual ~MyTabWidget(){}
    };
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    
    

    that is my mainwondows.cpp file

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        MyTabWidget* tabWidget = new MyTabWidget(this);
        TabBar* tabBar = new TabBar(this);
        tabWidget->setMyTabBar(tabBar);
    
        ui->centralWidget->layout()->addWidget(tabWidget);
    
        tabWidget->addTab(new QWidget(tabWidget),"tab1");
        tabWidget->addTab(new QWidget(tabWidget),"tab2");
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    

    another advise my friend ?

    regards



  • to know if i can update the value of the width of the tabs... and I that's the idea, i have to do the same every time when I resize the windows. Am I wrong ?

    You don't need to know. Basically, the code that lays out the tab should already be subscribed to the relevant signals / events, and should be calling your MyTabBar::tabSizeHint as necessary.

    Did you try my MyTabBar::tabSizeHint implementation above? ie

    QSize MyTabBar::tabSizeHint(int index) const {
        QSize size = QTabBar::tabSizeHint(index);
        if (expanding()) {
            // The exact value here probably doesn't matter; since we're expanding anyway, the tabs
            // will presumably all expand in even proportions, as they all have the same width hint.
            size.setWidth(1);
        }
        return size;
    }
    

    The trick here is that we're always returning the same width for all tabs, whereas your version will return different widths as tabs are added (or deleted).

    It might not work, but give it a try if you haven't already.

    Cheers.



  • I had a quick play, and it seems that setExpanding is not working as I expected... I'll have to look a little closer :)



  • @Paul-Colby
    Yes paaul, it doesn't work for me neither

    any other advise ?

    regards


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.