Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    How can set QTabWidget tabs in a certain order?

    General and Desktop
    5
    14
    13083
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      betmens last edited by

      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
      }
      @
      or
      @
      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?

      Thanks

      1 Reply Last reply Reply Quote 0
      • B
        betmens last edited by

        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
        @

        1 Reply Last reply Reply Quote 0
        • B
          betmens last edited by

          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.

          1 Reply Last reply Reply Quote 0
          • D
            dbzhang800 last edited by

            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.

            @
            ui->tabw_main->blockSignals(true);
            @

            and

            @
            ui->tabw_main->blockSignals(false);
            @

            1 Reply Last reply Reply Quote 0
            • N
              nehusharma last edited by

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

              1 Reply Last reply Reply Quote 0
              • A
                andre last edited by

                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.

                1 Reply Last reply Reply Quote 0
                • B
                  betmens last edited by

                  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")

                  1 Reply Last reply Reply Quote 0
                  • A
                    andre last edited by

                    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.

                    1 Reply Last reply Reply Quote 0
                    • B
                      betmens last edited by

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

                      1 Reply Last reply Reply Quote 0
                      • A
                        andre last edited by

                        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.

                        1 Reply Last reply Reply Quote 0
                        • B
                          betmens last edited by

                          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.

                          1 Reply Last reply Reply Quote 0
                          • A
                            andre last edited by

                            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?

                            1 Reply Last reply Reply Quote 0
                            • B
                              betmens last edited by

                              It's impossible :)
                              @QStringList list_default, list_user;
                              int i, n, from, to;
                              list_default<<"0"<<"1"<<"2"<<"3";
                              list_user<<"2"<<"0"<<"3"<<"1";
                              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 ???

                              1 Reply Last reply Reply Quote 0
                              • E
                                EastSide last edited by

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

                                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;
                                list_default<<"0"<<"1"<<"2"<<"3";
                                list_user<<"2"<<"0"<<"3"<<"1";
                                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...

                                1 Reply Last reply Reply Quote 0
                                • First post
                                  Last post