2

QComboBox で使用する QAbstractListView を作成しようとしています。この QComboBox は、含まれているアイテムの並べ替えられたリストを維持します。私の問題を示すサンプルコードを以下にいくつか含めました。リスト内の項目を更新すると、コンボ ボックスの currentIndex が更新されず、モデルへの変更が反映されません。rowsAboutToBeInserted シグナルと rowsInserted シグナルを使用してみましたが、効果が見られません (間違っているのでしょうか?)。

私の実際の使用例はもう少し複雑ですが、この例で十分です。並べ替えられるアイテムは単なる文字列ではなく、並べ替えるにはもう少し手間がかかり、DisplayRole とは異なる ItemDataRole を持ちます。

itemsAdded と itemsRemoved は私自身の関数であり、プロキシしようとしている別のリストからの信号に接続されます。

問題を引き起こすには、'Insert "c"' ボタンを押してください。文字列はリストに正しく挿入されますが、選択は 'e' から 'd' に移動します (つまり、選択インデックスは変更されません)。

サンプルコード

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui

class Model(QtCore.QAbstractListModel):
    def __init__(self, *args, **kwargs):
        QtCore.QAbstractListModel.__init__(self, *args, **kwargs)
        self.items = []

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.items)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid() is True:
            if role == QtCore.Qt.DisplayRole:
                return QtCore.QVariant(self.items[index.row()])
            elif role == QtCore.Qt.ItemDataRole:
                return QtCore.QVariant(self.items[index.row()])
        return QtCore.QVariant()

    def itemsAdded(self, items):
        # insert items into their sorted position
        items = sorted(items)
        row = 0
        while row < len(self.items) and len(items) > 0:
            if items[0] < self.items[row]:
                self.items[row:row] = [items.pop(0)]
                row += 1
            row += 1
        # add remaining items to end of list
        if len(items) > 0:
            self.items.extend(items)

    def itemsRemoved(self, items):
        # remove items from list
        for item in items:
            for row in range(0, len(self.items)):
                if self.items[row] == item:
                    self.items.pop(row)
                    break

def main():
    app = QtGui.QApplication([])
    w = QtGui.QWidget()
    w.resize(300,300)
    layout = QtGui.QVBoxLayout()

    model = Model()
    model.itemsAdded(['a','b','d','e'])

    combobox = QtGui.QComboBox()
    combobox.setModel(model)
    combobox.setCurrentIndex(3)
    layout.addWidget(combobox)

    def insertC(self):
        model.itemsAdded('c')

    button = QtGui.QPushButton('Insert "c"')
    button.clicked.connect(insertC)
    layout.addWidget(button)

    w.setLayout(layout)
    w.show()
    app.exec_()

if __name__ == '__main__':
    main()
4

2 に答える 2

1

選択インデックスを自分で変更する必要があると思います。つまり、次のようなものです

if row < currentIndex():
    setCurrentIndex( currentIndex() + 1 );

ただし、次の文章を読む必要があります。

サイズ変更可能なリストのようなデータ構造へのインターフェースを提供するモデルは、insertRows() および removeRows() の実装を提供できます。これらの関数を実装するときは、接続されているすべてのビューが変更を認識できるように、適切な関数を呼び出すことが重要です。

• insertRows() 実装は、新しい行をデータ構造に挿入する前に beginInsertRows() を呼び出す必要があり、その直後に endInsertRows() を呼び出す必要があります。

• removeRows() 実装は、行がデータ構造から削除される前に beginRemoveRows() を呼び出す必要があり、その直後に endRemoveRows() を呼び出す必要があります。

于 2013-06-21T09:13:08.673 に答える