Tabview issue
-
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.pngBad:
http://www.foto-jw.com/WrongTab.pngAnyone 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
-
Could you provide a simplified example demonstrating this behavior? It would make it a lot easier to see what's going wrong.
-
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: operatorTabsanchors.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
-
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.0Rectangle { 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(QStringLiteral("qml/test/main.qml")); 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
-
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.
-
Great, I'll just wait for 5.3 then.
Thanks!