QListViewの選択アイテムをDELキーで削除する!!




PySide(Qt)で、QListViewやらQTreeViewを使っていると、普通のアプリケーションでできる操作を入れたくなりますよね。今回は、QListViewでDeleteキーを押したら、選択しているアイテムを削除するコードをご紹介したいと思います!∠( ゚д゚)/

PySide(Qt)でキーを押した時の仕込みを入れたい場合は、「keyPressEvent」をオーバーライドすることで可能となります。もっともシンプルな状態のクラスが以下のようになります。

from PySide import QtCore
from PySide import QtGui

class ListView(QtGui.QListView):
	def __init__(self, *args, **kwargs):
		super(ListView, self).__init__(*args, **kwargs)
		
	def keyPressEvent(self, event):
		pass

次に、「keyPressEvent」の中身を作っていきたいと思います。

from PySide import QtCore
from PySide import QtGui

class ListView(QtGui.QListView):
	def __init__(self, *args, **kwargs):
		super(ListView, self).__init__(*args, **kwargs)
		
	def keyPressEvent(self, event):
		if event.key() == QtCore.Qt.Key_Delete:
			# 次の項目で選択したアイテムを削除するコードを書きます。
			return
			
		super(ListView, self).keyPressEvent(event)

押されたキーの情報は、引数の「event」から取り出すことができます。押されたキーが~だったら、この処理をするっといった条件分岐で実装していきましょう。

最後に、基底クラスの「keyPressEvent」を実行し忘れないようにしましょう。でないと、PySide(Qt)標準の機能の操作ができなくなってしまいます(;´∀`)

次に、選択したアイテムの削除を実装します。「keyPressEvent」に直接処理を書いてしまうと、オーバーライドした項目が見づらくなってしまいますので、「removeSelectedItem」というメソッドを用意して、「keyPressEvent」から呼び出す形にしたいと思います。

from PySide import QtCore
from PySide import QtGui

class ListView(QtGui.QListView):
	def __init__(self, *args, **kwargs):
		super(ListView, self).__init__(*args, **kwargs)
	
	def removeSelectedItem(self):
		model	 = self.model()
		selModel = self.selectionModel()
		
		while True:
			indexes = selModel.selectedIndexes()
			if not indexes:
				break
				
			model.removeRow(indexes[0].row())
				
	def keyPressEvent(self, event):
		if event.key() == QtCore.Qt.Key_Delete:
			self.removeSelectedItem()
			return
			
		super(ListView, self).keyPressEvent(event)

「removeSelectedItem」では、まずViewに設定されたモデルと、セレクションモデルを取得しています。これは、このクラスを直接使用せず、継承されて使われることを想定してこのような形にしています。

次に「while True」で、終了!っとするまで繰り返し処理をするようにしています。PySide(Qt)では、選択したアイテムを一度に消そうとしても、1つづつしか消すことができません。そのまま繰り返し処理で削除していくと、アイテムのIndexがずれていき、意図しないアイテムが消えていくようになります、、、(´;ω;`)

なので、選択された項目の1番目を削除して(この時に削除したアイテムの選択も外れます)、選択がなくなるまで繰り返すっという方法にしました。

Pythonでは多重継承もできますので、「QAbstractItemView」を継承してkeyPressEventを強化し、QListView、QTreeViewとMixするのも面白いかもしれませんね!