タブの名前をダブルクリックで編集する!!

タブを増やしたり、削除したりできるようにしていると、タブの名前も簡単に編集できるようにしたいなっと思いませんか!?

こんな感じで、タブをダブルクリックするとタブ名を編集できる方法をご紹介したいと思います!

クラスの骨格

タブをダブルクリックした時の仕組みをいれるには、QTabBarを継承して作成していきます!QTabBarは、名前の通りQTabWidgetで言うところのタブの部分のみのクラスになります。

from PySide import QtCore
from PySide import QtGui

class TabBar(QtGui.QTabBar):
	def __init__(self, *args, **kwargs):
		super(TabBar, self).__init__(*args, **kwargs)

シグナルの作成

今回は汎用的なクラスにしたいと思いますので、タブをダブルクリックした時のリネームの処理を直接書くのではなく、シグナルがでるようにしたいと思います。

こうすることで、リネームの処理を別のクラスに任せることができるので、タブ名を制限したり、リネームの方法を自由自在に書くことができます。

from PySide import QtCore
from PySide import QtGui

class TabBar(QtGui.QTabBar):
	doubleClicked = QtCore.Signal()
	def __init__(self, *args, **kwargs):
		super(TabBar, self).__init__(*args, **kwargs)

ダブルクリックの処理

ダブルクリックの処理を書くには、マウス操作のイベントをオーバーライドします。っということは、Qtでは「mousePressEvent」をオーバーライドするっということになりますね!(*´ω`*)

from PySide import QtCore
from PySide import QtGui

class TabBar(QtGui.QTabBar):
	doubleClicked = QtCore.Signal()
	def __init__(self, *args, **kwargs):
		super(TabBar, self).__init__(*args, **kwargs)
		
	def mousePressEvent(self, event):
		if event.type() == QtCore.QEvent.MouseButtonDblClick:# (1)
			if self.tabRect(self.currentIndex()).contains(event.pos()):#(3)
				self.doubleClicked.emit()#(4)
		
		else:
			super(TabBarPlus, self).mousePressEvent(event)#(2)

まず、引数のeventから、どういったマウス操作が行われたか調べます。今回はダブルクリックのみターゲットとしたいので、「MouseButtonDblClick」と一致するか調べます(1)。一致しない場合は、基底クラスの処理に委ねます(2)。

次は、ちょっと確認しておきたいことがあります。QTabBarの「mousePressEvent」は、どのエリアで行った時に発動すると思いますか?冒頭の画像でいうと、以下のエリアで発動します(`・ω・´)ゞ

おもったより広い範囲で発動しちゃいます。なので、ちゃんとタブがダブルクリックされたかということと、どのタブがダブルクリックされたかをキチンと調べる必要があります!

アクティブになっているタブは「self.currentIndex()」で調べられるので、このインデックスを使用して「self.tabRect」に指定し、タブのエリアの情報を取得します。

取得したデータはQRectになりますので、「contains」を使って、マウスがクリックされた位置情報と当たり判定を行います(3)。

当たり判定がTrueの場合は、先程作成したシグナル「doubleClicked」をemitします(4)。

QTabWidgetと組み合わせて使う

QTabBarだけですとあまり使用例がないと思いますので、QTabWidgetと組み合わせて使う方法を見ていきたいと思います。

class TabWidget(QtGui.QTabWidget):
	def __init__(self, *args, **kwargs):
		super(TabWidget, self).__init__(*args, **kwargs)
		
		tabBar = TabBar(self)
		tabBar.doubleClicked.connect(self.renameTab)#(2)
		self.setTabBar(tabBar)#(1)

 

カスタムしたTabBarをQTabWidgetで使用するには、TabBarのインスタンスを「setTabBar」を使って設定してあげるだけです(1)。

せっかくですので、実際のリネーム処理まで書いてみますのでシグナル「doubleClicked」と、後述のスロット「renameTab」をコネクションします。

リネーム処理の実装

新しいタブ名をサクッと頂きたいので、QInputDialogのgetTextを使いたいと思います。

class TabWidget(QtGui.QTabWidget):
	def __init__(self, *args, **kwargs):
		super(TabWidget, self).__init__(*args, **kwargs)
		
		tabBar = TabBar(self)
		tabBar.doubleClicked.connect(self.renameTab)
		self.setTabBar(tabBar)
	
	def renameTab(self):
		text, ok = QtGui.QInputDialog.getText(
					self,
					self.title,
					'Rename Tab Name',
					QtGui.QLineEdit.Normal,
					self.tabText(self.currentIndex())
					)#(1)
		if ok:
			self.setTabText(self.currentIndex(), text)

設定は大したものではありませんが、入力欄の初期値は現在のタブ名になっていると、使ってくれる人がリネームしやすくていいかと思います!ウザければ、空欄でもOKだと思います(1)。

入力後にOKをクリックされたら、「setTabText」を使ってタブ名を更新します。

これイイ!っと思ったら、是非使ってみてください!(*´ω`*)