9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[PyQt] QListWidgetでQStandardItemModelを使う

Last updated at Posted at 2015-10-27

PyQtの話ですが、基本はQtでも変わらないと思います。
あんまりC++のQtはわからないけれども。

model/view programimg

こまかいことはこっちで読んでください。

おおざっぱな話すると、
QTreeView, QListView, QTableViewという3つのView classは
QFileSystemModel, QStandardItemModel, QTableWidgetModel, etcといったModel classによって
大まかな挙動や表示が来まる。
使い方はこんな感じ。

QTreeView
class MyTreeView(QTreeViw):
    def __init__(self,parent=None):
        super(MyTreeView,self).__init__(parent)
        model = QFileSystemModel()
        model.setRootPath('')
        self.setModel(model)
        self.setRootIndex(model.index(os.path.expanduser('~')))

def main():
    app = QApplication(sys.argv)

    view = MyTreeView()
    view.show()

    app.exec_()

if __name__ == '__main__':
    main()

デフォルトのQListWidget

QTreeView, QListView, QTableViewにはそれぞれQTreeWidget, QListWidget, QTableWidgetがある。
今回使ったのはQListWidget。
QListWidgetでアイテムを追加するにはデフォルトだとこうする。

QListWidget
class MyListWidget(QListWidget):
    def __init__(self,parent=None):
        super(MyListWidget,self).__init__(parent)
        self.addItem('first row')
        self.addItem('second row')


def main():
    app = QApplication(sys.argv)

    view = MyListWidget()
    view.show()

    app.exec_()

if __name__ == '__main__':
    main()

打って変わってModelとかViewとか関係なく動く。

QListWidgetでQStandardItemModelを使う

ちょっとListアイテムをドラッグアウトしたときに埋め込む情報を弄りたくて
QStandardItem & QStandardItemModelを使うことにした。
その場合、アイテムの追加方法が変わる。

QListWidget
class MyListWidget(QListWidget):
    def __init__(self,parent=None):
        super(MyListWidget,self).__init__(parent)
        self.model = QStandardItemModel(self)
        self.view = QListView(self)
        self.view.setModel(self.model)
        self.model.appendRow(QStandardItem('first row'))
        self.model.appendRow(QStandardItem('second row'))

def main():
    app = QApplication(sys.argv)

    view = MyListWidget()
    view.show()

    app.exec_()

if __name__ == '__main__':
    main()

今度はアイテムの管理はQListWidget上では行わない。
QListWidgetはQListViewの親として表示する場所を与えるだけ。
QListViewもアイテムの管理を行わず、modelを表示するだけ。
肝心のアイテムはmodelで管理される。
modelをいじればViewが変わってWidgetに適応される、自動で。

QListwidgetでQStandardItemModelを使い、Drag&Dropする

で、更に面倒なのがこれ。
もともと、デフォルトのQListWidgetを使う場合は次のようにしてD&Dを設定する。

QListWidget
class MyListWidget(QListWidget):
    def __init__(self,parent=None):
        super(MyListWidget,self).__init__(parent)
        self.setAcceptDrops(True)
        self.setDragEnabled(True)
        self.setDragDropMode(QAbstractItemView.InternalMove)

    def dragEnterEvent(self,event):
        hogehoge

    def dragMoveEvent(self,event):
        hogehoge

    def dropEvent(self,event):
        hogehoge


def main():
    app = QApplication(sys.argv)

    view = MyListWidget()
    view.show()

    app.exec_()

if __name__ == '__main__':
    main()

ところが、QStandardItemModelをセットするとD&Dの設定はWidgetじゃなくてViewで行う。

QListWidget
class MyListWidget(QListWidget):
    def __init__(self,parent=None):
        super(MyListWidget,self).__init__(parent)
        self.view = MyListView(self)

class MyListView(QListView):
    def __init__(self,parent=None):
        super(MyListView,self).__init__(parent)
        self.model = QStandardItemModel()
        self.setModel(self.model)
        self.setAcceptDrops(True)
        self.setDragEnabled(True)
        self.setDragDropMode(QAbstractItemView.InternalMove)

    def dragEnterEvent(self,event):
        hogehoge

    def dragMoveEvent(self,event):
        hogehoge

    def dropEvent(self,event):
        hogehoge


def main():
    app = QApplication(sys.argv)

    view = MyListWidget()
    view.show()

    app.exec_()

if __name__ == '__main__':
    main()

これがわからず結構ハマった。

9
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?