klikli234 发表于 2024-4-18 16:08:27

pyside6 的 Qlistwidget 清空后 重新加入元素后崩溃请问是怎么导致的

本帖最后由 klikli234 于 2024-4-18 21:07 编辑

不知道怎么回事. 我检查了对象好像也没有被销毁就莫名奇妙崩溃了, 看代码
# This Python file uses the following encoding: utf-8
import sys

from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QMainWindow, QListWidgetItem

# Important:
# You need to run the following command to generate the ui_form.py file
#   pyside6-uic form.ui -o ui_form.py, or
#   pyside2-uic form.ui -o ui_form.py
from ui_form import Ui_MainWindow

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
      super().__init__(parent)
      self.ui = Ui_MainWindow()
      self.ui.setupUi(self)

      item1 = QListWidgetItem("task 1")
      item2 = QListWidgetItem("task 2")

      self.ui.listWidget.addItem(item1)
      self.ui.listWidget.addItem(item2)

      action_data_list: List = []
      action_data_list_2: List = []
      action_data_list.append(QListWidgetItem("action 1"))
      action_data_list.append(QListWidgetItem("action 2"))

      self.ui.listWidget_2.addItem(action_data_list)
      self.ui.listWidget_2.addItem(action_data_list)

      item1.setData(Qt.UserRole, action_data_list)
      item2.setData(Qt.UserRole, action_data_list_2)

      self.ui.listWidget.itemClicked.connect(self.reload)

    # reload item to listWidget_2
    def reload(self):
      current_item = self.ui.listWidget.currentItem()
      action_data_list = current_item.data(Qt.UserRole)
      for i in range(self.ui.listWidget_2.count()):
            self.ui.listWidget_2.takeItem(0)
      self.ui.listWidget_2.clear()
      for action_data in action_data_list:
            self.ui.listWidget_2.addItem(action_data)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    widget = MainWindow()
    widget.show()
    sys.exit(app.exec())


调用reload 函数就会导致这个问题.请帮我看看,非常感谢.

FishC 发表于 2024-4-18 16:08:51

问题出在reload函数中的两行代码:

for i in range(self.ui.listWidget_2.count()):
    self.ui.listWidget_2.takeItem(0)

这段代码的目的是清空`listWidget_2`中的所有项。但是,在调用`takeItem()`方法时,你使用了固定的索引值0。这意味着每次都只会删除第一个项,而不是逐个删除所有项。

更好的做法是使用`takeItem()`方法的返回值来进行循环删除,直到没有项为止。修改后的`reload()`函数如下所示:

def reload(self):
    current_item = self.ui.listWidget.currentItem()
    action_data_list = current_item.data(Qt.UserRole)
    while self.ui.listWidget_2.count() > 0:
      item = self.ui.listWidget_2.takeItem(0)
      del item
    for action_data in action_data_list:
      self.ui.listWidget_2.addItem(action_data)

现在,每次调用`reload()`函数时,都会正确地清空`listWidget_2`中的所有项,并重新添加新的元素。希望能帮助到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

klikli234 发表于 2024-4-18 16:16:36

FishC 发表于 2024-4-18 16:08
问题出在reload函数中的两行代码:




for i in range(self.ui.listWidget_2.count()):
    self.ui.listWidget_2.takeItem(0)

是正确清空了的, 但是在清空后, 重新载入就会崩溃.

FishC 发表于 2024-4-18 16:16:59

klikli234 发表于 2024-04-18 16:16
for i in range(self.ui.listWidget_2.count()):
    ...

非常抱歉,我刚才理解错了你的问题。

在重新加载`listWidget_2`时,你需要注意避免重复添加相同的项导致崩溃。在你的代码中,你首先定义了两个空列表:`action_data_list`和`action_data_list_2`,然后两个列表都添加了相同的项。这样会导致在重新加载时,向`listWidget_2`中重复添加相同的项,从而引发崩溃。

要解决这个问题,你可以修改一下代码,在重新加载之前,先清空列表,然后再重新添加新的项。修改后的`reload()`函数如下所示:

def reload(self):
    current_item = self.ui.listWidget.currentItem()
    action_data_list = current_item.data(Qt.UserRole)

    self.ui.listWidget_2.clear()# 清空listWidget_2中的所有项

    for action_data in action_data_list:
      self.ui.listWidget_2.addItem(action_data)

这样修改后,应该就能够正确地重新加载`listWidget_2`了,不会再出现崩溃的问题。希望能帮到你!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

klikli234 发表于 2024-4-18 16:19:25

FishC 发表于 2024-4-18 16:16
非常抱歉,我刚才理解错了你的问题。

在重新加载`listWidget_2`时,你需要注意避免重复添加相同的项 ...

self.ui.listWidget_2.clear()
会删除数据, 可能只能用TakeItem来做

FishC 发表于 2024-4-18 16:19:56

klikli234 发表于 2024-04-18 16:19
self.ui.listWidget_2.clear()
会删除数据, 可能只能 ...

非常抱歉,我之前的回答有误。确实,`clear()`方法会将列表中的项删除,但是它同时也会删除与这些项相关联的数据。在你的代码中,通过设置`Qt.UserRole`来关联数据,所以使用`clear()`方法会导致数据也被删除。

在重新加载之前,你可以先逐个使用`takeItem()`方法将列表框中的项移除,然后再重新添加新的项。修改后的`reload()`函数如下所示:

def reload(self):
    current_item = self.ui.listWidget.currentItem()
    action_data_list = current_item.data(Qt.UserRole)
   
    # 清空listWidget_2中的所有项
    while self.ui.listWidget_2.count() > 0:
      item = self.ui.listWidget_2.takeItem(0)
      del item
   
    # 重新添加新的项
    for action_data in action_data_list:
      self.ui.listWidget_2.addItem(action_data)

这样修改后,应该就能够正确地重新加载`listWidget_2`了。希望这次能够解决你的问题!非常抱歉给你带来困扰。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

klikli234 发表于 2024-4-18 21:07:02

FishC 发表于 2024-4-18 16:19
非常抱歉,我之前的回答有误。确实,`clear()`方法会将列表中的项删除,但是它同时也会删除与这些项相 ...

pyside6 的问题 换到pyside2 解决

FishC 发表于 2024-4-18 21:07:15

klikli234 发表于 2024-04-18 21:07
pyside6 的问题 换到pyside2 解决

非常抱歉之前的回答没有解决你的问题。如果你切换到 PySide2,可以尝试以下方法来解决清空列表后重新添加元素导致崩溃的问题:

首先,确保你已经安装了 PySide2 库。

然后,修改 `reload` 函数如下:

def reload(self):
    current_item = self.ui.listWidget.currentItem()
    action_data_list = current_item.data(Qt.UserRole)
   
    # 清空listWidget_2中的所有项
    self.ui.listWidget_2.clear()
   
    # 重新添加新的项
    for action_data in action_data_list:
      item = QListWidgetItem(action_data)
      self.ui.listWidget_2.addItem(item)

在这个修改后的代码中,我们使用 `clear()` 方法来清空 `listWidget_2` 中的所有项,并且通过 `QListWidgetItem` 类重新创建新的项,并将其添加到 `listWidget_2` 中。

这样修改后,应该就不会再出现崩溃的问题了。希望这次能够解决你的问题!如果仍有困惑,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1]
查看完整版本: pyside6 的 Qlistwidget 清空后 重新加入元素后崩溃请问是怎么导致的