【问题标题】:PyQt: QListView drag and drop reordering signal issuePyQt:QListView 拖放重新排序信号问题
【发布时间】:2015-11-11 16:32:02
【问题描述】:

我在使用 QListView 和 QStandardItemModel 实现拖放重新排序时遇到了一些麻烦。使用 itemChanged 信号处理选中的项目很好,但是当使用拖放重新排序项目时,似乎在触发信号时创建了一个临时项目。列表中有 5 个项目,但是每次重新排序项目时,模型行数变为 6,即使最后只有 5 个可见。为什么当我专门设置动作移动时它会暂时变成6?我只想处理新订单中的 5 个项目,因为该列表直接用于更新另一个小部件。我尝试了 dataChange 信号,但没有任何区别。

我的设置是 Win 7 上的 PyQt 4.11.4 和 Python 2.7.10。

import sys

from PyQt4.QtGui import *
from PyQt4.QtCore import *

if __name__ == '__main__':
    app = QApplication(sys.argv)

    # Our main window will be a QListView
    list = QListView()
    list.setDragDropMode(QAbstractItemView.InternalMove)
    list.setDefaultDropAction(Qt.MoveAction)
    list.setDragDropOverwriteMode(False)
    list.setAcceptDrops(True)
    list.setDropIndicatorShown(True)
    list.setDragEnabled(True)
    list.setWindowTitle('Example List')
    list.setMinimumSize(600, 400)

    # Create an empty model for the list's data
    model = QStandardItemModel(list)

    # Add some textual items
    foods = [
        'pizza',
        'burger',
        'steak',
        'chips',
        'soda'
    ]

    for food in foods:
        # create an item with a caption
        item = QStandardItem(food)

        # add a checkbox to it
        item.setCheckable(True)
        item.setData({'one': 1, 'two': 2, 'three': 3})
        item.setDragEnabled(True)
        item.setDropEnabled(False)

        # Add the item to the model
        model.appendRow(item)

    def on_item_changed(item):
        # If the changed item is not checked, don't bother checking others
        print 'DEBUG model rowcount'
        print model.rowCount()
        print 'itemChanged'
        if not item.checkState():
            return

        # Loop through the items until you get None, which
        # means you've passed the end of the list
        i = 0
        while model.item(i):
            if not model.item(i).checkState():
                return
            i += 1

        app.quit()

    model.itemChanged.connect(on_item_changed)

    # Apply the model to the list view
    list.setModel(model)

    w = QMainWindow()
    w.setCentralWidget(list)
    w.show()

    sys.exit(app.exec_())

【问题讨论】:

    标签: python pyqt pyqt4


    【解决方案1】:

    更新,我找到了一个解决方法,它涉及使用单次计时器。在列表中删除一个项目后,计时器会触发插槽,它会以新顺序找到 5 个项目,而不是 6 个。

    import sys
    
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
    
        # Our main window will be a QListView
        list = QListView()
        list.setDragDropMode(QAbstractItemView.InternalMove)
        list.setDefaultDropAction(Qt.MoveAction)
        list.setDragDropOverwriteMode(False)
        list.setAcceptDrops(True)
        list.setDropIndicatorShown(True)
        list.setDragEnabled(True)
        list.setWindowTitle('Example List')
        list.setMinimumSize(600, 400)
    
        # Create an empty model for the list's data
        model = QStandardItemModel(list)
    
        # Add some textual items
        foods = [
            'pizza',
            'burger',
            'steak',
            'chips',
            'soda'
        ]
    
        for food in foods:
            # create an item with a caption
            item = QStandardItem(food)
    
            # add a checkbox to it
            item.setCheckable(True)
            item.setData({'one': 1, 'two': 2, 'three': 3})
            item.setDragEnabled(True)
            item.setDropEnabled(False)
    
            # Add the item to the model
            model.appendRow(item)
    
        def showModelCount():
            print 'DEBUG rowcount after singleshot'
            print model.rowCount()
    
        def on_item_changed(item):
            # If the changed item is not checked, don't bother checking others
            print 'DEBUG model rowcount'
            print model.rowCount()
    
            QTimer.singleShot(1, showModelCount)
    
            print 'itemChanged'
            if not item.checkState():
                return
    
            # Loop through the items until you get None, which
            # means you've passed the end of the list
            i = 0
            while model.item(i):
                if not model.item(i).checkState():
                    return
                i += 1
    
            app.quit()
    
        model.itemChanged.connect(on_item_changed)
    
        # Apply the model to the list view
        list.setModel(model)
    
        w = QMainWindow()
        w.setCentralWidget(list)
        w.show()
    
        sys.exit(app.exec_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-19
      • 2013-05-11
      • 2012-05-31
      相关资源
      最近更新 更多