QTabWidgetに追加ボタンを作る!!part2

QTabWidgetに追加ボタンを作る!!part1に続いて、前回問題だった「setTabsClosable」と「setMovable」の併用を踏まえて、別の方法で「+」ボタンを追加してみましょう!

前回はタブの一番右側でしたが、今回は、タブの右上(TabBarの右側)にボタンが配置されます!ちょっとMayaとかと違うけど、悪くないレイアウトですね!

クラスの作成

まずは、QTabWidgetを継承した「TabWidget」のクラスから用意したいと思います!こちらは、QTabWidgetに追加ボタンを作る!!part1と同じ内容になります。

class TabWidget(QtGui.QTabWidget):
    def __init__(self, *args, **kwargs):
        super(TabWidget, self).__init__(*args, **kwargs)

タブ追加のボタン

「QTabWidget」にある「setCornerWidget」を使って、タブエリアの右上にボタンを追加します!∠( ゚д゚)/

from PySide import QtGui
class TabWidget(QtGui.QTabWidget):
    def __init__(self, *args, **kwargs):
        super(TabWidget, self).__init__(*args, **kwargs)
        
        addButton = QtGui.QPushButton('+', self)
        addButton.setFlat(True)
        self.setCornerWidget(addButton)
        
        self.insertTab(0, QtGui.QWidget(), 'Tab1'))

今回の例は、「+」ボタンを「QPushButton」で作成し、「setFlat」を使ってボタンの枠線を消しています。作成したボタンは、「QTabWidget」にある「setCornerWidget」を使って設定すれば、タブエリア(TabBar)の右上に表示されます。

今回はQPushButtonでしたが、QToolButtonや、アイコンを併用したボタンなどお好みで制作していただければと思います(`・ω・´)ゞ

タブが1つも登録されていないと、何も表示されないのでご注意ください!

タブ追加の実装

タブの追加処理は、外部から干渉されないようにプライベートにしました。こちらはお好みで変更してください。
from PySide import QtGui
class TabWidget(QtGui.QTabWidget):
    def __init__(self, *args, **kwargs):
        super(TabWidget, self).__init__(*args, **kwargs)
        
        addButton = QtGui.QPushButton('+', self)
        addButton.setFlat(True)
        self.setCornerWidget(addButton)
        
        self.insertTab(0, QtGui.QWidget(), 'Tab1')
        
    def __addTab(self):
        index = self.count()
        newTabName, status = QtGui.QInputDialog.getText(
                self,
                'Add New Tab',
                'Specify new tab name',
                QtGui.QLineEdit.Normal,
                'Tab%d' % (index+1)
                )
         
        if not status:
            return
         
        self.insertTab(index, QtGui.QWidget(), newTabName)
        self.setCurrentIndex(index)

まず初めにタブの総数を「count」を使用して調べます。この値をタブの追加や、切り替えのIndexとして使用します。それ以外の部分は、QTabWidgetに追加ボタンを作る!!part1と同じ内容です。

シグナルの設定

このままでは、「+」のタブをクリックしても反応しませんので、Signal & Slotの設定を「__init__」に追加します。

from PySide import QtGui
class TabWidget(QtGui.QTabWidget):
    def __init__(self, *args, **kwargs):
        super(TabWidget, self).__init__(*args, **kwargs)
        
        addButton = QtGui.QPushButton('+', self)
        addButton.setFlat(True)
        addButton.clicked.connect(self.__addTab)
        self.setCornerWidget(addButton)
        
        self.insertTab(0, QtGui.QWidget(), 'Tab1')
        
    def __addTab(self):
        index = self.count()
        newTabName, status = QtGui.QInputDialog.getText(
                self,
                'Add New Tab',
                'Specify new tab name',
                QtGui.QLineEdit.Normal,
                'Tab%d' % (index+1)
                )
         
        if not status:
            return
         
        self.insertTab(index, QtGui.QWidget(), newTabName)
        self.setCurrentIndex(index)
        
window = QtGui.QMainWindow()
tab = TabWidget(window)
window.setCentralWidget(tab)
window.show()

setTabsClosableとsetMovableの確認

「__init__」の部分に、「setTabsClosable」と「setMovable」の設定を追加し、「+」との併用に問題がないか見てみます!

from PySide import QtGui
class TabWidget(QtGui.QTabWidget):
    def __init__(self, *args, **kwargs):
        super(TabWidget, self).__init__(*args, **kwargs)
        self.setTabsClosable(True)
        self.setMovable(True)
        
        addButton = QtGui.QPushButton('+', self)
        addButton.setFlat(True)
        addButton.clicked.connect(self.__addTab)
        self.setCornerWidget(addButton)
        
        self.insertTab(0, QtGui.QWidget(), 'Tab1')
        
    def __addTab(self):
        index = self.count()
        newTabName, status = QtGui.QInputDialog.getText(
                self,
                'Add New Tab',
                'Specify new tab name',
                QtGui.QLineEdit.Normal,
                'Tab%d' % (index+1)
                )
         
        if not status:
            return
         
        self.insertTab(index, QtGui.QWidget(), newTabName)
        self.setCurrentIndex(index)
        
window = QtGui.QMainWindow()
tab = TabWidget(window)
window.setCentralWidget(tab)
window.show()

早速してみると、以下の画像のように、タブにのみ「X」が追加されました!そもそも「+」はタブではないから、大丈夫ですね、、、(;´∀`)

タブ削除の実装

「setTabsClosable」を設定しただけでは、ボタンが表示されるだけで、実際に削除することはできません、、、まぎらわしい、、、(;´∀`)

せっかくですので、タブの削除の実装を見ていきたいとお思いまーーーーっす!∠( ゚д゚)/

from PySide import QtGui
class TabWidget(QtGui.QTabWidget):
    def __init__(self, *args, **kwargs):
        super(TabWidget, self).__init__(*args, **kwargs)
        self.setTabsClosable(True)
        self.setMovable(True)
        self.tabCloseRequested.connect(self.__removeTab)
        
        addButton = QtGui.QPushButton('+', self)
        addButton.setFlat(True)
        addButton.clicked.connect(self.__addTab)
        self.setCornerWidget(addButton)
        
        self.insertTab(0, QtGui.QWidget(), 'Tab1')
        
    def __addTab(self):
        index = self.count()
        newTabName, status = QtGui.QInputDialog.getText(
                self,
                'Add New Tab',
                'Specify new tab name',
                QtGui.QLineEdit.Normal,
                'Tab%d' % (index+1)
                )
         
        if not status:
            return
         
        self.insertTab(index, QtGui.QWidget(), newTabName)
        self.setCurrentIndex(index)
        
    def __removeTab(self, index):
        if self.count() >= 2:
            self.removeTab(index)

「X」が押された時のアクションは、Signal「tabCloseRequested」が用意されています!「__init__」の部分に「__removeTab」を実行するように設定しました。

Signal「tabCloseRequested」は、「X」が押されたIndexを引数で渡してくるので、メソッド「__removeTab」で受け取れるように引数を設定しておきます。

タブが全て削除されてしまうと、QTabWidgetがグレー一色になってしまいますので、「count」を使って「タブが2個以上の場合だけ削除する」ようにするといいとお思います!

これで、QTabWidgetを使って、動的に追加したり、削除したり、並び替えたりできるようになったかと思います!(*´ω`*)b