Add QgsTabWidget

This is almost like the QTabWidget but has additional methods for
showing and hiding individual tabs
This commit is contained in:
Matthias Kuhn 2016-09-09 08:07:13 +02:00
parent 9626f589fb
commit ac41436de3
7 changed files with 426 additions and 0 deletions

View File

@ -161,6 +161,7 @@
%Include qgssourceselectdialog.sip
%Include qgssublayersdialog.sip
%Include qgssvgannotationitem.sip
%Include qgstabwidget.sip
%Include qgstablewidgetitem.sip
%Include qgstextannotationitem.sip
%Include qgstrackedvectorlayertools.sip

View File

@ -0,0 +1,69 @@
/***************************************************************************
qgstabwidget.sip - QgsTabWidget
---------------------
begin : 8.9.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/** \ingroup gui
* The QgsTabWidget class is the same as the QTabWidget but with additional methods to
* temporarily hide/show tabs.
*
* @note Added in QGIS 3.0
*/
class QgsTabWidget : QTabWidget
{
%TypeHeaderCode
#include <qgstabwidget.h>
%End
public:
/**
* Create a new QgsTabWidget with the optionally provided parent.
*
* @note Added in QGIS 3.0
*/
QgsTabWidget( QWidget *parent = nullptr );
/**
* Hides the tab with the given widget
*
* @note Added in QGIS 3.0
*/
void hideTab( QWidget* tab );
/**
* Shows the tab with the given widget
*
* @note Added in QGIS 3.0
*/
void showTab( QWidget* tab );
/**
* Control the visibility for the tab with the given widget.
*
* @note Added in QGIS 3.0
*/
void setTabVisible( QWidget* tab, bool visible );
/**
* Returns the index of the tab with the given widget.
* This index is not the same as the one provided to insertTab and removeTab
* since these methods are not aware of hidden tabs.
*
* @note Added in QGIS 3.0
*/
int realTabIndex( QWidget* widget );
virtual void tabInserted( int index );
virtual void tabRemoved( int index );
};

View File

@ -299,6 +299,7 @@ SET(QGIS_GUI_SRCS
qgssublayersdialog.cpp
qgssqlcomposerdialog.cpp
qgssvgannotationitem.cpp
qgstabwidget.cpp
qgstablewidgetitem.cpp
qgstextannotationitem.cpp
qgstrackedvectorlayertools.cpp
@ -451,6 +452,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsslider.h
qgssqlcomposerdialog.h
qgssublayersdialog.h
qgstabwidget.h
qgstreewidgetitem.h
qgsunitselectionwidget.h
qgsuserinputdockwidget.h

159
src/gui/qgstabwidget.cpp Normal file
View File

@ -0,0 +1,159 @@
/***************************************************************************
qgstabwidget.cpp - QgsTabWidget
---------------------
begin : 8.9.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgstabwidget.h"
#include "qgslogger.h"
QgsTabWidget::QgsTabWidget( QWidget* parent )
: QTabWidget( parent )
, mSetTabVisibleFlag( false )
{
}
void QgsTabWidget::hideTab( QWidget* tab )
{
QgsDebugMsg( "Hide" );
TabInformation& info = mTabs[ realTabIndex( tab )];
if ( info.visible )
{
mSetTabVisibleFlag = true;
removeTab( info.sourceIndex );
info.visible = false;
mSetTabVisibleFlag = false;
}
}
void QgsTabWidget::showTab( QWidget* tab )
{
QgsDebugMsg( "Show" );
TabInformation& info = mTabs[ realTabIndex( tab )];
if ( ! info.visible )
{
mSetTabVisibleFlag = true;
insertTab( info.sourceIndex + 1, info.widget, info.label );
info.visible = true;
mSetTabVisibleFlag = false;
}
}
void QgsTabWidget::setTabVisible( QWidget* tab, bool visible )
{
if ( visible )
showTab( tab );
else
hideTab( tab );
}
int QgsTabWidget::realTabIndex( QWidget* widget )
{
int realIndex = 0;
Q_FOREACH ( const TabInformation& info, mTabs )
{
if ( info.widget == widget )
return realIndex;
++realIndex;
}
return -1;
}
void QgsTabWidget::tabInserted( int index )
{
if ( !mSetTabVisibleFlag )
{
QWidget* newWidget = widget( index );
if ( index == 0 )
{
mTabs.insert( 0, TabInformation( newWidget, tabText( index ) ) );
}
else
{
bool inserted = false;
QList<TabInformation>::iterator it;
for ( it = mTabs.begin(); it != mTabs.end(); ++it )
{
if ( it->sourceIndex == index )
{
mTabs.insert( it, TabInformation( newWidget, tabText( index ) ) );
inserted = true;
break;
}
}
if ( !inserted )
{
mTabs.append( TabInformation( newWidget, tabText( index ) ) );
}
}
}
synchronizeIndexes();
}
void QgsTabWidget::tabRemoved( int index )
{
if ( !mSetTabVisibleFlag )
{
QList<TabInformation>::iterator it;
for ( it = mTabs.begin(); it != mTabs.end(); ++it )
{
if ( it->sourceIndex == index )
{
mTabs.removeOne( *it );
break;
}
}
}
synchronizeIndexes();
}
void QgsTabWidget::synchronizeIndexes()
{
QgsDebugMsg( "---------" );
int i = -1;
QWidget* nextWidget = widget( 0 );
QList<TabInformation>::iterator it;
for ( it = mTabs.begin(); it != mTabs.end(); ++it )
{
if ( it->widget == nextWidget )
{
i++;
nextWidget = widget( i + 1 );
}
it->sourceIndex = i;
QgsDebugMsg( QString( "Tab %1 (%2): %3" ).arg( it->sourceIndex ).arg( it->label ).arg( i ) );
}
}
QgsTabWidget::TabInformation QgsTabWidget::tabInfo( QWidget* widget )
{
Q_FOREACH ( const TabInformation& info, mTabs )
{
if ( info.widget == widget )
return info;
}
return TabInformation();
}
bool QgsTabWidget::TabInformation::operator ==( const QgsTabWidget::TabInformation& other )
{
return other.widget == widget && other.sourceIndex == sourceIndex;
}

104
src/gui/qgstabwidget.h Normal file
View File

@ -0,0 +1,104 @@
/***************************************************************************
qgstabwidget.h - QgsTabWidget
---------------------
begin : 8.9.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSTABWIDGET_H
#define QGSTABWIDGET_H
#include <QTabWidget>
/** \ingroup gui
* The QgsTabWidget class is the same as the QTabWidget but with additional methods to
* temporarily hide/show tabs.
*
* @note Added in QGIS 3.0
*/
class GUI_EXPORT QgsTabWidget : public QTabWidget
{
Q_OBJECT
public:
/**
* Create a new QgsTabWidget with the optionally provided parent.
*
* @note Added in QGIS 3.0
*/
QgsTabWidget( QWidget *parent = nullptr );
/**
* Hides the tab with the given widget
*
* @note Added in QGIS 3.0
*/
void hideTab( QWidget* tab );
/**
* Shows the tab with the given widget
*
* @note Added in QGIS 3.0
*/
void showTab( QWidget* tab );
/**
* Control the visibility for the tab with the given widget.
*
* @note Added in QGIS 3.0
*/
void setTabVisible( QWidget* tab, bool visible );
/**
* Returns the index of the tab with the given widget.
* This index is not the same as the one provided to insertTab and removeTab
* since these methods are not aware of hidden tabs.
*
* @note Added in QGIS 3.0
*/
int realTabIndex( QWidget* widget );
virtual void tabInserted( int index );
virtual void tabRemoved( int index );
private:
void synchronizeIndexes();
struct TabInformation
{
TabInformation( QWidget* wdg, const QString& lbl )
: sourceIndex( -1 )
, widget( wdg )
, label( lbl )
, visible( true )
{}
TabInformation()
: sourceIndex( -1 )
, widget( nullptr )
, visible( true )
{}
bool operator ==( const TabInformation& other );
int sourceIndex;
QWidget* widget;
QString label;
bool visible;
};
TabInformation tabInfo( QWidget* widget );
QList<TabInformation> mTabs;
bool mSetTabVisibleFlag;
};
#endif // QGSTABWIDGET_H

View File

@ -81,6 +81,7 @@ ADD_PYTHON_TEST(PyQgsRulebasedRenderer test_qgsrulebasedrenderer.py)
ADD_PYTHON_TEST(PyQgsSingleSymbolRenderer test_qgssinglesymbolrenderer.py)
ADD_PYTHON_TEST(PyQgsShapefileProvider test_provider_shapefile.py)
ADD_PYTHON_TEST(PyQgsTabfileProvider test_provider_tabfile.py)
ADD_PYTHON_TEST(PyQgsTabWidget test_qgstabwidget.py)
ADD_PYTHON_TEST(PyQgsOGRProvider test_provider_ogr.py)
ADD_PYTHON_TEST(PyQgsSearchWidgetToolButton test_qgssearchwidgettoolbutton.py)
ADD_PYTHON_TEST(PyQgsSearchWidgetWrapper test_qgssearchwidgetwrapper.py)

View File

@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-
'''
test_qgstabwidget.py
--------------------------------------
Date : September 2016
Copyright : (C) 2016 Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
'''
import qgis # NOQA
from qgis.testing import unittest
from qgis.gui import QgsTabWidget
from qgis.PyQt.QtGui import QApplication, QWidget
class TestQgsTabWidget(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.app = QApplication([])
def setUp(self):
"""Run before each test."""
pass
def tearDown(self):
"""Run after each test."""
pass
def testQgsTabWidget(self):
tabWidget = QgsTabWidget()
wdg1 = QWidget()
wdg2 = QWidget()
wdg3 = QWidget()
wdg4 = QWidget()
tabWidget.addTab(wdg1, '1')
tabWidget.addTab(wdg2, '2')
tabWidget.addTab(wdg3, '3')
tabWidget.hideTab(wdg2)
self.assertEquals(tabWidget.count(), 2)
tabWidget.showTab(wdg2)
self.assertEquals(tabWidget.count(), 3)
self.assertEquals(tabWidget.tabText(0), '1')
self.assertEquals(tabWidget.tabText(1), '2')
self.assertEquals(tabWidget.tabText(2), '3')
tabWidget.hideTab(wdg2)
tabWidget.removeTab(1)
self.assertEquals(tabWidget.tabText(0), '1')
tabWidget.showTab(wdg2)
self.assertEquals(tabWidget.tabText(1), '2')
self.assertEquals(tabWidget.count(), 2)
# Show an already visible tab
tabWidget.showTab(wdg2)
self.assertEquals(tabWidget.count(), 2)
# Hide twice
tabWidget.hideTab(wdg2)
self.assertEquals(tabWidget.count(), 1)
tabWidget.hideTab(wdg2)
self.assertEquals(tabWidget.count(), 1)
tabWidget.hideTab(wdg1)
self.assertEquals(tabWidget.count(), 0)
tabWidget.showTab(wdg1)
tabWidget.showTab(wdg2)
self.assertEquals(tabWidget.count(), 2)
tabWidget.removeTab(0)
self.assertEquals(tabWidget.count(), 1)
tabWidget.hideTab(wdg2)
self.assertEquals(tabWidget.count(), 0)
if __name__ == '__main__':
unittest.main()