Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Tabview issue

Tabview issue

Scheduled Pinned Locked Moved QML and Qt Quick
6 Posts 2 Posters 3.3k Views 1 Watching
  • 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.
  • M Offline
    M Offline
    MattieB
    wrote on last edited by
    #1

    Hi,

    In my application i have a main.qml file which has a loader which loads the content on the screen dependent on which state the application is in.
    One of the states is a TabView with 3 tabs. From the 3rd tab I can switch to a new state and from this state I can switch back to the 'tabview' state.
    When I switch back from this new state to the tabview state, I want my tabview to have the third tab active. I did this by binding the currentIndex of the TabView component to a variable in my state object (which is a QObject). This seems to work, except that the rendering of the tabview is kinda messed up after I switch back: the third tab is shown as the active tab, but it seems like the content of this tab is moved up until the top anchor point of the tab(instead of the bottom anchor point). Also the border is drawn to high.
    Good:
    http://www.foto-jw.com/NormalTab.png

    Bad:
    http://www.foto-jw.com/WrongTab.png

    Anyone has an idea what is wrong? (If i don't bind the currentIndex property, the first tab is active and it's content is shown correct (anchored to the bottom of the tab))
    Regards,

    Matt

    1 Reply Last reply
    0
    • J Offline
      J Offline
      Jens
      wrote on last edited by
      #2

      Could you provide a simplified example demonstrating this behavior? It would make it a lot easier to see what's going wrong.

      1 Reply Last reply
      0
      • M Offline
        M Offline
        MattieB
        wrote on last edited by
        #3

        I'll try:

        main.qml
        @
        Rectangle
        {
        width: 1366
        height: 768
        Loader
        {

        id:loader
        source: stateMachineQMLInterface.activeStateQmlLocation;
        anchors.fill: parent
        }
        }
        @

        OperatorMain.qml (source file for the 'tabview' state)
        @
        Item
        {
        anchors.fill: parent;

        TabView
        {
        id: operatorTabs

        anchors.left: parent.left;
        anchors.leftMargin: 5;
        anchors.top: parent.top;
        anchors.topMargin: 5;

        width: parent.width - 10;
        height: parent.height - 10;

        currentIndex: operatorMainStateQMLInterface.currentTabIndex;
        Binding
        {
        target: operatorMainStateQMLInterface;
        property: "currentTabIndex";
        value: operatorTabs.currentIndex;
        }
        Tab
        {
        title: "Jobs";
        source: operatorJobManagementStateQMLInterface.getLocationOfQmlFile();
        }
        Tab
        {
        title: "System Monitor";
        source: operatorSystemMonitoringStateQMLInterface.getLocationOfQmlFile();
        }
        Tab
        {
        title: "History";
        source: operatorHistoryStateQMLInterface.getLocationOfQmlFile();
        }
        }
        }
        @

        OperatorMainStateQMLInterface.cpp:
        @
        class AMSOperatorMainStateQMLInterface : public AMSIStateQMLInterface
        {
        Q_OBJECT
        Q_PROPERTY(int currentTabIndex READ getCurrentTabIndex WRITE setCurrentTabIndex NOTIFY currentTabIndexChanged);
        }
        @

        (AMSIStateQMLInterface implements the methods for getLocationOfQmlFile and registers it's contextProperty to the viewers rootContext)

        When the state changes, the stateMachineQMLInterface.activeStateQmlLocationChanged signal is emitted, so the loader loads
        the new qml file (belonging to the new state). When I pop this state (the 'tabview' state is stored in the statemachine), again the
        activeStateQmlLocationChanged signal is emitted, so the qml file OperatorMain.qml is loaded (with the currentIndex bound to the
        qproperty in the stored state in the statemachine). When this is shown on screen, i get the wrong behaviour of the tabs.
        Hope this makes it more clear.
        Regards,

        Matt

        1 Reply Last reply
        0
        • M Offline
          M Offline
          MattieB
          wrote on last edited by
          #4

          I've got a more simple case which shows the error:

          Main.qml
          @
          import QtQuick 2.0
          import QtQuick.Layouts 1.0
          import QtQuick.Controls 1.0

          Rectangle {
          width: 800
          height: 600
          color: "red"
           
          TabView
          {
          id: operatorTabs
           
          anchors.left: parent.left;
          anchors.leftMargin: 5;
          anchors.top: parent.top;
          anchors.topMargin: 5;
           
          width: parent.width - 10;
          height: parent.height - 10;
           
          currentIndex: tabContext.tabIndex;
          Binding
          {
          target: tabContext;
          property: "tabIndex";
          value: operatorTabs.currentIndex;
          } 
          Tab
          {
          title: "Jobs";
          Rectangle
          {
          anchors.fill: parent
          color: "green"
          }
          }
          Tab
          {
          title: "System Monitor";
          Rectangle
          {
          anchors.fill: parent
          color: "yellow"
          }
          } 
          Tab
          {
          title: "History";
          Rectangle
          {
          anchors.fill: parent
          color: "blue"
          }
          }
          }
          }
          

          @
          TabContext.h
          @
          #ifndef TABCONTEXT_H
          #define TABCONTEXT_H

          #pragma warning(push, 0)
          #include <qobject.h>
          #pragma warning(pop)
           
           
          class TabContext : public QObject
          {
          Q_OBJECT
          Q_PROPERTY(int tabIndex READ getTabIndex WRITE setTabIndex NOTIFY tabIndexChanged);
           
          public:
          TabContext ();
          virtual ~TabContext (void);
           
          public: 
          int getTabIndex () const;
          void setTabIndex (int index);
           
           
          signals:
          void tabIndexChanged ();
           
          private:
          int _tabIndex;
          };
           
          #endif
          

          @

          TabContext.cpp
          @
          #include "TabContext.h"

          TabContext::TabContext(void)
          : _tabIndex(0)
          {
          }
           
           
          TabContext::~TabContext(void)
          {
          }
           
           
          int TabContext::getTabIndex() const
          {
          return _tabIndex;
          }
           
          void TabContext::setTabIndex(int index)
          {
          if(index != _tabIndex)
          {
          _tabIndex = index;
          emit tabIndexChanged();
          }
          }
          

          @

          Main.cpp
          @
          #pragma warning(push, 0)
          #include "qtquick2applicationviewer.h"
          #pragma warning(pop)

          #include "TabContext.h"
           
          #pragma warning(push, 0)
          #include <QtGui/QGuiApplication>
          #include <QtQml/qqmlcontext.h>
          #pragma warning(pop)
          #pragma warning(push, 0)
          #include <qobject.h>
          #include <qstringlist.h>
          #pragma warning(pop)
           
           
          #include "qtquick2applicationviewer.h"
           
          int main(int argc, char *argv[])
          {
          QGuiApplication app(argc, argv);
           
          QtQuick2ApplicationViewer viewer;
          TabContext context;
           
          viewer.rootContext()->setContextProperty(QString("tabContext"), &context);
           
          viewer.setMainQmlFile&#40;QStringLiteral("qml/test/main.qml"&#41;);
          viewer.showExpanded();
           
          return app.exec();
          }
          

          @

          If in TabContext, _tabIndex is initiallised as 0, everything is ok, if it is 1 or 2, the content from the tabs is drawn too high (the yellow and the blue square starts at the same level as the top of the tab-label, while it should start at the bottom of it).
          Anybody an idea, or is it just a bug in Qt?
          Regards,

          Matt

          1 Reply Last reply
          0
          • J Offline
            J Offline
            Jens
            wrote on last edited by
            #5

            Just an update. I have now fixed this issue for 5.3.

            https://codereview.qt-project.org/#change,82917

            Unfortunately I don't have a practical workaround for older versions apart from modifying the deployed QML sources with the above mentioned fix. Though you could set the index in "onCompleted" but that would result in pretty ugly flickering.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              MattieB
              wrote on last edited by
              #6

              Great, I'll just wait for 5.3 then.
              Thanks!

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved