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するのも面白いかもしれませんね!