Skip to content

Commit ac41436

Browse files
committed
Add QgsTabWidget
This is almost like the QTabWidget but has additional methods for showing and hiding individual tabs
1 parent 9626f58 commit ac41436

File tree

7 files changed

+426
-0
lines changed

7 files changed

+426
-0
lines changed

python/gui/gui.sip

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@
161161
%Include qgssourceselectdialog.sip
162162
%Include qgssublayersdialog.sip
163163
%Include qgssvgannotationitem.sip
164+
%Include qgstabwidget.sip
164165
%Include qgstablewidgetitem.sip
165166
%Include qgstextannotationitem.sip
166167
%Include qgstrackedvectorlayertools.sip

python/gui/qgstabwidget.sip

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/***************************************************************************
2+
qgstabwidget.sip - QgsTabWidget
3+
4+
---------------------
5+
begin : 8.9.2016
6+
copyright : (C) 2016 by Matthias Kuhn
7+
email : matthias@opengis.ch
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
17+
/** \ingroup gui
18+
* The QgsTabWidget class is the same as the QTabWidget but with additional methods to
19+
* temporarily hide/show tabs.
20+
*
21+
* @note Added in QGIS 3.0
22+
*/
23+
class QgsTabWidget : QTabWidget
24+
{
25+
%TypeHeaderCode
26+
#include <qgstabwidget.h>
27+
%End
28+
29+
public:
30+
/**
31+
* Create a new QgsTabWidget with the optionally provided parent.
32+
*
33+
* @note Added in QGIS 3.0
34+
*/
35+
QgsTabWidget( QWidget *parent = nullptr );
36+
37+
/**
38+
* Hides the tab with the given widget
39+
*
40+
* @note Added in QGIS 3.0
41+
*/
42+
void hideTab( QWidget* tab );
43+
44+
/**
45+
* Shows the tab with the given widget
46+
*
47+
* @note Added in QGIS 3.0
48+
*/
49+
void showTab( QWidget* tab );
50+
51+
/**
52+
* Control the visibility for the tab with the given widget.
53+
*
54+
* @note Added in QGIS 3.0
55+
*/
56+
void setTabVisible( QWidget* tab, bool visible );
57+
58+
/**
59+
* Returns the index of the tab with the given widget.
60+
* This index is not the same as the one provided to insertTab and removeTab
61+
* since these methods are not aware of hidden tabs.
62+
*
63+
* @note Added in QGIS 3.0
64+
*/
65+
int realTabIndex( QWidget* widget );
66+
67+
virtual void tabInserted( int index );
68+
virtual void tabRemoved( int index );
69+
};

src/gui/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ SET(QGIS_GUI_SRCS
299299
qgssublayersdialog.cpp
300300
qgssqlcomposerdialog.cpp
301301
qgssvgannotationitem.cpp
302+
qgstabwidget.cpp
302303
qgstablewidgetitem.cpp
303304
qgstextannotationitem.cpp
304305
qgstrackedvectorlayertools.cpp
@@ -451,6 +452,7 @@ SET(QGIS_GUI_MOC_HDRS
451452
qgsslider.h
452453
qgssqlcomposerdialog.h
453454
qgssublayersdialog.h
455+
qgstabwidget.h
454456
qgstreewidgetitem.h
455457
qgsunitselectionwidget.h
456458
qgsuserinputdockwidget.h

src/gui/qgstabwidget.cpp

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/***************************************************************************
2+
qgstabwidget.cpp - QgsTabWidget
3+
4+
---------------------
5+
begin : 8.9.2016
6+
copyright : (C) 2016 by Matthias Kuhn
7+
email : matthias@opengis.ch
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
#include "qgstabwidget.h"
17+
18+
#include "qgslogger.h"
19+
20+
QgsTabWidget::QgsTabWidget( QWidget* parent )
21+
: QTabWidget( parent )
22+
, mSetTabVisibleFlag( false )
23+
{
24+
}
25+
26+
void QgsTabWidget::hideTab( QWidget* tab )
27+
{
28+
QgsDebugMsg( "Hide" );
29+
TabInformation& info = mTabs[ realTabIndex( tab )];
30+
if ( info.visible )
31+
{
32+
mSetTabVisibleFlag = true;
33+
removeTab( info.sourceIndex );
34+
info.visible = false;
35+
mSetTabVisibleFlag = false;
36+
}
37+
}
38+
39+
void QgsTabWidget::showTab( QWidget* tab )
40+
{
41+
QgsDebugMsg( "Show" );
42+
TabInformation& info = mTabs[ realTabIndex( tab )];
43+
if ( ! info.visible )
44+
{
45+
mSetTabVisibleFlag = true;
46+
insertTab( info.sourceIndex + 1, info.widget, info.label );
47+
info.visible = true;
48+
mSetTabVisibleFlag = false;
49+
}
50+
}
51+
52+
void QgsTabWidget::setTabVisible( QWidget* tab, bool visible )
53+
{
54+
if ( visible )
55+
showTab( tab );
56+
else
57+
hideTab( tab );
58+
}
59+
60+
int QgsTabWidget::realTabIndex( QWidget* widget )
61+
{
62+
int realIndex = 0;
63+
Q_FOREACH ( const TabInformation& info, mTabs )
64+
{
65+
if ( info.widget == widget )
66+
return realIndex;
67+
++realIndex;
68+
}
69+
return -1;
70+
}
71+
72+
void QgsTabWidget::tabInserted( int index )
73+
{
74+
if ( !mSetTabVisibleFlag )
75+
{
76+
QWidget* newWidget = widget( index );
77+
78+
if ( index == 0 )
79+
{
80+
mTabs.insert( 0, TabInformation( newWidget, tabText( index ) ) );
81+
}
82+
else
83+
{
84+
bool inserted = false;
85+
QList<TabInformation>::iterator it;
86+
87+
for ( it = mTabs.begin(); it != mTabs.end(); ++it )
88+
{
89+
if ( it->sourceIndex == index )
90+
{
91+
mTabs.insert( it, TabInformation( newWidget, tabText( index ) ) );
92+
inserted = true;
93+
break;
94+
}
95+
}
96+
97+
if ( !inserted )
98+
{
99+
mTabs.append( TabInformation( newWidget, tabText( index ) ) );
100+
}
101+
}
102+
}
103+
104+
synchronizeIndexes();
105+
}
106+
107+
void QgsTabWidget::tabRemoved( int index )
108+
{
109+
if ( !mSetTabVisibleFlag )
110+
{
111+
QList<TabInformation>::iterator it;
112+
113+
for ( it = mTabs.begin(); it != mTabs.end(); ++it )
114+
{
115+
if ( it->sourceIndex == index )
116+
{
117+
mTabs.removeOne( *it );
118+
break;
119+
}
120+
}
121+
}
122+
123+
synchronizeIndexes();
124+
}
125+
126+
void QgsTabWidget::synchronizeIndexes()
127+
{
128+
QgsDebugMsg( "---------" );
129+
int i = -1;
130+
QWidget* nextWidget = widget( 0 );
131+
132+
QList<TabInformation>::iterator it;
133+
134+
for ( it = mTabs.begin(); it != mTabs.end(); ++it )
135+
{
136+
if ( it->widget == nextWidget )
137+
{
138+
i++;
139+
nextWidget = widget( i + 1 );
140+
}
141+
it->sourceIndex = i;
142+
QgsDebugMsg( QString( "Tab %1 (%2): %3" ).arg( it->sourceIndex ).arg( it->label ).arg( i ) );
143+
}
144+
}
145+
146+
QgsTabWidget::TabInformation QgsTabWidget::tabInfo( QWidget* widget )
147+
{
148+
Q_FOREACH ( const TabInformation& info, mTabs )
149+
{
150+
if ( info.widget == widget )
151+
return info;
152+
}
153+
return TabInformation();
154+
}
155+
156+
bool QgsTabWidget::TabInformation::operator ==( const QgsTabWidget::TabInformation& other )
157+
{
158+
return other.widget == widget && other.sourceIndex == sourceIndex;
159+
}

src/gui/qgstabwidget.h

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/***************************************************************************
2+
qgstabwidget.h - QgsTabWidget
3+
4+
---------------------
5+
begin : 8.9.2016
6+
copyright : (C) 2016 by Matthias Kuhn
7+
email : matthias@opengis.ch
8+
***************************************************************************
9+
* *
10+
* This program is free software; you can redistribute it and/or modify *
11+
* it under the terms of the GNU General Public License as published by *
12+
* the Free Software Foundation; either version 2 of the License, or *
13+
* (at your option) any later version. *
14+
* *
15+
***************************************************************************/
16+
#ifndef QGSTABWIDGET_H
17+
#define QGSTABWIDGET_H
18+
19+
#include <QTabWidget>
20+
21+
/** \ingroup gui
22+
* The QgsTabWidget class is the same as the QTabWidget but with additional methods to
23+
* temporarily hide/show tabs.
24+
*
25+
* @note Added in QGIS 3.0
26+
*/
27+
class GUI_EXPORT QgsTabWidget : public QTabWidget
28+
{
29+
Q_OBJECT
30+
31+
public:
32+
/**
33+
* Create a new QgsTabWidget with the optionally provided parent.
34+
*
35+
* @note Added in QGIS 3.0
36+
*/
37+
QgsTabWidget( QWidget *parent = nullptr );
38+
39+
/**
40+
* Hides the tab with the given widget
41+
*
42+
* @note Added in QGIS 3.0
43+
*/
44+
void hideTab( QWidget* tab );
45+
46+
/**
47+
* Shows the tab with the given widget
48+
*
49+
* @note Added in QGIS 3.0
50+
*/
51+
void showTab( QWidget* tab );
52+
53+
/**
54+
* Control the visibility for the tab with the given widget.
55+
*
56+
* @note Added in QGIS 3.0
57+
*/
58+
void setTabVisible( QWidget* tab, bool visible );
59+
60+
/**
61+
* Returns the index of the tab with the given widget.
62+
* This index is not the same as the one provided to insertTab and removeTab
63+
* since these methods are not aware of hidden tabs.
64+
*
65+
* @note Added in QGIS 3.0
66+
*/
67+
int realTabIndex( QWidget* widget );
68+
69+
virtual void tabInserted( int index );
70+
virtual void tabRemoved( int index );
71+
72+
private:
73+
void synchronizeIndexes();
74+
75+
struct TabInformation
76+
{
77+
TabInformation( QWidget* wdg, const QString& lbl )
78+
: sourceIndex( -1 )
79+
, widget( wdg )
80+
, label( lbl )
81+
, visible( true )
82+
{}
83+
84+
TabInformation()
85+
: sourceIndex( -1 )
86+
, widget( nullptr )
87+
, visible( true )
88+
{}
89+
90+
bool operator ==( const TabInformation& other );
91+
92+
int sourceIndex;
93+
QWidget* widget;
94+
QString label;
95+
bool visible;
96+
};
97+
98+
TabInformation tabInfo( QWidget* widget );
99+
100+
QList<TabInformation> mTabs;
101+
bool mSetTabVisibleFlag;
102+
};
103+
104+
#endif // QGSTABWIDGET_H

tests/src/python/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ ADD_PYTHON_TEST(PyQgsRulebasedRenderer test_qgsrulebasedrenderer.py)
8181
ADD_PYTHON_TEST(PyQgsSingleSymbolRenderer test_qgssinglesymbolrenderer.py)
8282
ADD_PYTHON_TEST(PyQgsShapefileProvider test_provider_shapefile.py)
8383
ADD_PYTHON_TEST(PyQgsTabfileProvider test_provider_tabfile.py)
84+
ADD_PYTHON_TEST(PyQgsTabWidget test_qgstabwidget.py)
8485
ADD_PYTHON_TEST(PyQgsOGRProvider test_provider_ogr.py)
8586
ADD_PYTHON_TEST(PyQgsSearchWidgetToolButton test_qgssearchwidgettoolbutton.py)
8687
ADD_PYTHON_TEST(PyQgsSearchWidgetWrapper test_qgssearchwidgetwrapper.py)

0 commit comments

Comments
 (0)