How can set QTabWidget tabs in a certain order?

  • Form(project.ui) consisting from movable QTabWidget(tabw_main) with QWidgets (tab_1, tab_2, tab_3)
    Program user in opened program can move tabs. For example (tab_3, tab_1, tab_2)
    When program quits, tab sequence is saving with join function how QString "tab_3,tab_1,tab_2" in program settings table.
    In the next time, when user open program, with split function is simply to get QStringList ("tab_3", "tab_1", "tab_2")
    Currently I trying following:
    QWidget *w;
    QString t = "tab_3,tab_1,tab_2";
    foreach (QString v, t.split(",")) {
    w = findChild<QWidget *>(v);//get the necessary widget
    //... can't find here solution
    QStringList list = t.split(",");
    int n = list.count();
    for (int i = 0; i < n; ++i) {
    w = findChild<QWidget *>(list[i]);//get the necessary widget
    //... can't find here solution
    How to set tabs in following order?


  • Find solution
    QString t = "tab_3,tab_1,tab_2";
    foreach (QString v, t.split(","))
    ui->tabw_main->addTab(findChild<QWidget *>(v), txt(v)); //where txt(v) is function which return texts in multiple languages from database

  • It works, but problem is still active. It is not best solution because procedure:
    @void Project::on_tabw_main_currentChanged(QWidget *arg) {
    repeated each time when tab is added.

  • Hi betments,

    If you want to avoid this slot to be called when you add Tabs, you can add following statements before and after you operation.




  • hi batnaens,
    if you want solved this problem then you have to add statement before and after you operation.
    thank you:)

  • Well, QTabWidget provides access to it's embedded QTabBar instance via tabBar(), and [[doc:QTabBar]] has a method moveTab(int from, int to). If you don't want to subclass your QTabWidget, you can use QObject::findChildren<QTabBar*>() on your QTabWidget to get a pointer to the QTabBar.

  • Thanks Andre.
    @QStringList tb_main_list;
    Project::Project(QWidget *parent) : QMainWindow(parent), ui(new Ui::Project) {
    tb_main = ui->tabwMain->findChild<QTabBar *>("qt_tabwidget_tabbar");
    int n = tb_main->count();
    for (int i = 0; i < n; ++i) tb_main_list << QString::number(i);//("0", "1", "2", "3") save as default tab order. Needed if programmatically change tab count.
    connect(tb_main, SIGNAL(tabMoved(int, int)), this, SLOT(tab_order(int, int)));
    //when tab is moved, change also tb_main_list order
    void Project::tab_order(int to, int from){
    QString t1 = tb_main_list[from], t2 = tb_main_list[to];
    tb_main_list[from] = t2;
    tb_main_list[to] = t1;
    But here is mathematical problem for me :)
    for example I have saved tab order ("3", "0", "2", "1")
    How can I change with moveTab(int from, int to) ("0", "1", "2", "3") to ("3", "0", "2", "1")?
    With for (int i = 0; i < n; ++i) list << tb_main_list.indexOf(i) I can get also ("1", "3", "2", "0"). That will be helpful if moveTab(0, 3) changed from ("0", "1", "2", "3") to ("3", "1", "2", "0"), but result is ("1", "2", "3", "0")

  • moveTab is not switchTab, of course. The move of the tab seems clear to me. The tab at index 0 ("0") is taken from the array, and then re-inserted at postition 3 (the end of the sequence). When taking "0" from the array, all other items move one position to the left, hence your result.

  • For me it's not so clear. With one day effort I can't find solution.
    Maybe someone can help with real example?

  • OK, here are the moves needed to reorder your tabs:

    You start with the order "0", "1", "2", "3", and your goal is "3", "0", "2", "1". I think it is easiest to order them simply starting at the front of the rows of tabs. So, starting with position 0, each time you move the tab you want at that position to that index. The tabs you already ordered will not be affected, as they are already at the right place so only the tabs behind it will change index.

    start "0", "1", "2", "3"
    move 0: "3", "0", "1", "2" // move from 3 to 0
    move 1: "3", "0", "1", "2" // move from 1 to 1: no move needed
    move 2: "3", "0", "2", "1" // move from 3 to 2

    Note that the "to" index is equal to the move number, and equal to the index in the row of tabs we're fixing. Also note that the "from" index is always >= to the "to" index, thus we're never messing up the work we already did.

  • Andre. It’s understand how works move. But it is problematic to write algorithm for every situation.
    Program allow to save settings for each n user.

  • No, it's not that hard...

    Just start at the start of your wanted sequence, locate each page, and put the in the front of the pages stack like I showed above. How hard is that?

  • It's impossible :)
    @QStringList list_default, list_user;
    int i, n, from, to;
    n = list.count(); //or list.count() - 1
    for (i = 0; i < n; ++i) {
    from = ???;
    to = ???;
    tb_main->moveTab(from, to);
    Seems I tried everything in ???

  • [quote author="betmens" date="1333654853"]It's impossible :)

    Yes, it's possible! ;)
    You must iterate through list from the end to the begining.
    Here is the example (maybe will be useful for somebody, if it's to late for you):

    QStringList list_default, list_user;
    int i, n, from, to;
    n = list_user.count() - 1
    for (i = n; i > -1; i--) {
    list_element = list_user[i];
    to = i;
    from = list_default.index(list_element);

    list_default.insert(to, list_default.pop(from)); // keep default list consistent
    tb_main->moveTab(from, to);

    Sorry for the possible program syntax errors (line 11 maybe), in above example - most time I programming in PyQt, so I am not much familiar with C++ & Qt...

Log in to reply

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