У меня есть PyQt5 QListview со списком элементов, которые можно изменить, перетаскивая и выбрав флажок.Проблема в том, что когда я переставляю элементы в списке, они правильно переставляются в графическом интерфейсе, но когда я пытаюсь сохранить выходные данные, появляется копия перемещенного элемента как в исходном, так и в новом положении.
Функция длясоздание списка
def create_methods_list(self):
self.methods_list = QListView()
self.methods_list.setDragDropMode(QListView.InternalMove)
self.methods_list.setDefaultDropAction(Qt.MoveAction)
self.methods_list.setDragDropMode(False)
self.methods_list.setAcceptDrops(True)
self.methods_list.setDropIndicatorShown(True)
self.methods_list.setDragEnabled(True)
self.methods_list.setWindowTitle('Method Order')
self.methods_model = QtGui.QStandardItemModel(self.methods_list)
# self.methods is a list of strings
for method in self.methods:
item = QtGui.QStandardItem(method)
item.setData(method)
item.setCheckable(True)
item.setDragEnabled(True)
item.setDropEnabled(False)
item.setCheckState(True)
self.methods_model.appendRow(item)
self.methods_model.itemChanged.connect(self.method_item_changed)
self.methods_list.setModel(self.methods_model)
Функция, вызываемая при перестановке списка:
def method_item_changed(self):
print(self.methods_model.rowCount())
i = 0
new_methods = []
while self.methods_model.item(i):
if self.methods_model.item(i).checkState():
new_methods.append(self.methods_model.item(i).data())
i += 1
print(new_methods)
self.methods = new_methods
Первый оператор print возвращает на единицу больше, чем количество элементов в исходном списке.Второй оператор print возвращает элементы в списке, но перемещенный элемент находится как в исходном, так и в новом положении.
Я пробовал решение, которое включало добавление QTimer с коротким интервалом, но это не сработало.
Любая помощь будет принята с благодарностью.
Полная рабочая версия:
from PyQt5.QtWidgets import (
QAction, QWidget, QLabel, QDesktopWidget,
QApplication, QComboBox, QPushButton, QGridLayout,
QMainWindow, qApp, QVBoxLayout, QSlider,
QHBoxLayout, QLineEdit, QListView, QAbstractItemView
)
from PyQt5.QtCore import Qt
from PyQt5 import QtGui
import sys
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.methods = ['option 1', 'option 2', 'option 3']
self.central_widget = QWidget(self)
self.layout = QVBoxLayout(self.central_widget)
self.layout.addStretch()
self.create_methods_list()
self.layout.addWidget(self.methods_list)
self.layout.addStretch()
self.setCentralWidget(self.central_widget)
self.show()
def create_methods_list(self):
self.methods_list = QListView()
self.methods_list.setDragDropMode(QListView.InternalMove)
self.methods_list.setDefaultDropAction(Qt.MoveAction)
self.methods_list.setDragDropMode(False)
self.methods_list.setAcceptDrops(True)
self.methods_list.setDropIndicatorShown(True)
self.methods_list.setDragEnabled(True)
self.methods_list.setWindowTitle('Method Order')
self.methods_model = QtGui.QStandardItemModel(self.methods_list)
for method in self.methods:
item = QtGui.QStandardItem(method)
item.setData(method)
item.setCheckable(True)
item.setDragEnabled(True)
item.setDropEnabled(False)
item.setCheckState(True)
self.methods_model.appendRow(item)
self.methods_model.itemChanged.connect(self.method_item_changed)
self.methods_list.setModel(self.methods_model)
self.methods_list.setMinimumHeight(
self.methods_list.sizeHintForRow(0)
* (self.methods_model.rowCount() + 2))
def method_item_changed(self):
print(self.methods_model.rowCount())
i = 0
new_methods = []
while self.methods_model.item(i):
if self.methods_model.item(i).checkState():
new_methods.append(self.methods_model.item(i).data())
i += 1
self.methods = new_methods
print(self.methods)
if __name__=='__main__':
app = QApplication(sys.argv)
ex = MainWindow()
ex.show()
sys.exit(app.exec_())