need help about QlistWidget.data() problem(crashed without noticed)
-
here is the thing
every single Task Item include Action list I use QlistWidgetItem[] to save it
if I clicked task item. the action view area well reload data from taskitem.data().
when task every single item has no action data when you switch task item the program well not crash.
when there is only one task item with action data won't crash
but when you switch the task item that had action item the program well crash.
# This Python file uses the following encoding: utf-8 import sys import copy from PySide6.QtCore import Signal, Slot, QRect, Qt, QPoint from PySide6.QtGui import QPalette, QColor, QMouseEvent, QPen, QPainter from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, 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 from datamanager import ActionData from newtaskdialog import NewTaskDialog from newmouseactiondialog import NewMouseActionDialog class Rect: def __init__(self, rect: QRect): self._rect = rect self._is_hover = False self._is_drag = False self._is_edge_drag = False class RenderArea(QWidget): signal_move_event = Signal(QMouseEvent) signal_release_event = Signal() def __init__(self, parent=None): super().__init__(parent) self.setMouseTracking(True) self._mouse_x = 0 self._mouse_y = 0 self._previous_mouse_pos = None # 初始绘图相关 self.pen = QPen(Qt.blue, 3) self.rect_list = [] def isRectIncludeMouse(self, mouse_pos: QPoint, rect: QRect): cursor_x = mouse_pos.x() cursor_y = mouse_pos.y() edge_weight = 8 if(cursor_x >= rect.x() and cursor_x <= rect.x() + rect.width() - edge_weight and cursor_y >= rect.y() and cursor_y <= rect.y() + rect.height() - edge_weight ): return True else: return False def isMouseOnRectEdge(self, mouse_pos: QPoint, rect: QRect): cursor_x = mouse_pos.x() cursor_y = mouse_pos.y() edge_weight = 8 if(cursor_x <= rect.x() + rect.width() and cursor_x > rect.x() + rect.width() - edge_weight and cursor_y <= rect.y() + rect.height() and cursor_y > rect.y() + rect.height() - edge_weight ): return True else: return False def mousePressEvent(self, event: QMouseEvent): self._previous_mouse_pos = event.position().toPoint() is_there_one_drag = False is_there_one_edge_drag = False for rect_index in range(len(self.rect_list)): if (self.isRectIncludeMouse(event.position().toPoint(), self.rect_list[rect_index]._rect) and not is_there_one_drag): self.rect_list[rect_index]._is_drag = True is_there_one_drag = True elif(self.isMouseOnRectEdge(event.position().toPoint(), self.rect_list[rect_index]._rect) and not is_there_one_edge_drag): self.rect_list[rect_index]._is_edge_drag = True is_there_one_edge_drag = True def mouseReleaseEvent(self, event: QMouseEvent): for rect_index in range(len(self.rect_list)): self.rect_list[rect_index]._is_drag = False self.rect_list[rect_index]._is_edge_drag = False self.signal_release_event.emit() def mouseMoveEvent(self, event: QMouseEvent): for rect_index in range(len(self.rect_list)): if self.rect_list[rect_index]._is_drag: new_rect_x = (event.position().x() - self._previous_mouse_pos.x()) + self.rect_list[rect_index]._rect.x() new_rect_y = (event.position().y() - self._previous_mouse_pos.y()) + self.rect_list[rect_index]._rect.y() if new_rect_x >= 0 and new_rect_x <= self.width(): self.rect_list[rect_index]._rect.moveTo(new_rect_x, self.rect_list[rect_index]._rect.y()) if new_rect_y >= 0 and new_rect_y <= self.height(): self.rect_list[rect_index]._rect.moveTo(self.rect_list[rect_index]._rect.x(), new_rect_y) self._previous_mouse_pos = event.position().toPoint() elif self.rect_list[rect_index]._is_edge_drag: new_rect_widght = (event.position().x() - self._previous_mouse_pos.x()) + self.rect_list[rect_index]._rect.width() new_rect_height = (event.position().y() - self._previous_mouse_pos.y()) + self.rect_list[rect_index]._rect.height() if new_rect_widght < 16: new_rect_widght = 16 if new_rect_height < 16: new_rect_height = 16 self.rect_list[rect_index]._rect.setWidth(new_rect_widght) self.rect_list[rect_index]._rect.setHeight(new_rect_height) self._previous_mouse_pos = event.position().toPoint() self.update() self.signal_move_event.emit(event) QWidget.mouseMoveEvent(self, event) def paintEvent(self, event): # 绘制一个矩形 with QPainter(self) as painter: painter.setPen(self.pen) for rect in self.rect_list: if rect._is_hover: painter.save() pen = QPen(Qt.red, 3) painter.setPen(pen) painter.drawRect(rect._rect) painter.restore() else: painter.drawRect(rect._rect) # 碰撞检查 # 拖动 class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # new action type dick self.action_type_dict = { "启动游戏": 0, "释放游戏": 1, "鼠标": 2, "键盘": 3, } # self.setMouseTracking(True) self._NewTaskDialog = NewTaskDialog() self._NewTaskDialog.hide() self._new_mouse_action_dialog = NewMouseActionDialog() self._new_mouse_action_dialog.hide() # 绘制区域初始化 self._render_area = RenderArea() # 设置背景颜色 back_ground_palette = QPalette() back_ground_palette.setColor(QPalette.Window, QColor(200, 200, 200)) self._render_area.setPalette(back_ground_palette) self._render_area.setAutoFillBackground(True) # 设置布局,加入父窗口 right_widget_layout = QHBoxLayout() right_widget_layout.addWidget(self._render_area) self.ui.widget_right.setLayout(right_widget_layout) # 新建 Task slot self.ui.pushButtonNewTask.clicked.connect(self.OpenNewTaskDialog) # 编辑 Task self.ui.listWidgetTaskList.itemDoubleClicked.connect(self.OpenEditTaskDialog) self.ui.listWidgetTaskList.itemClicked.connect(self.TaskItemSelected) # delete Task self.ui.pushButtonDeleteTask.clicked.connect(self.DeleteTask) # 添加或修改 Task slot self._NewTaskDialog.signal_add_clicked.connect(self.AddNewTask) self._NewTaskDialog.signal_edit_clicked.connect(self.EditTask) # Move up or Move Down Task slot self.ui.pushButtonTaskMoveUp.clicked.connect(self.TaskMoveUp) self.ui.pushButtonTaskMoveDown.clicked.connect(self.TaskMoveDown) # new action slot self.ui.pushButtonNewAction.clicked.connect(self.OpenNewActionDialog) self.ui.listWidgetActionList.itemDoubleClicked.connect(self.OpenEditActionDialog) self.ui.pushButtonDeleteAction.clicked.connect(self.DeleteAction) self.ui.listWidgetActionList.itemClicked.connect(self.ActionItemSelected) # new mouse action slot self._new_mouse_action_dialog.signal_add_confirm_clicked.connect(self.AddMouseAction) self._new_mouse_action_dialog.signal_edit_confirm_clicked.connect(self.EditMouseAction) # Move up and Move down action slot self.ui.pushButtonActionMoveUp.clicked.connect(self.ActionMoveUp) self.ui.pushButtonActionMoveDown.clicked.connect(self.ActionMoveDown) #update mouse position self._render_area.signal_move_event.connect(self.UpdateStatus) self._render_area.signal_release_event.connect(self.SaveRect) @Slot() def OpenNewTaskDialog(self): self._NewTaskDialog.OpenNewDialog() @Slot() def OpenEditTaskDialog(self): self._NewTaskDialog.OpenEditDialog(self.ui.listWidgetTaskList.currentItem().text()) @Slot() def TaskItemSelected(self): current_item = self.ui.listWidgetTaskList.currentItem() action_data_list = current_item.data(Qt.UserRole) for i in range(self.ui.listWidgetActionList.count()): self.ui.listWidgetActionList.takeItem(0) for action_data in action_data_list: self.ui.listWidgetActionList.addItem(action_data) @Slot() def DeleteTask(self): current_row = self.ui.listWidgetTaskList.currentRow() if self.ui.listWidgetTaskList.count() > 0 and current_row >= 0: self.ui.listWidgetTaskList.takeItem(current_row) @Slot() def AddNewTask(self, name: str): item = QListWidgetItem() item.setText(name) action_data_list: List[QListWidgetItem] = [] item.setData(Qt.UserRole, action_data_list) self.ui.listWidgetTaskList.addItem(item) @Slot() def EditTask(self, name: str): currenttask = self.ui.listWidgetTaskList.currentItem() currenttask.setText(name) self.ui.listWidgetTaskList.setCurrentItem(currenttask) @Slot() def TaskMoveUp(self): current_row = self.ui.listWidgetTaskList.currentRow() if current_row > 0 and self.ui.listWidgetTaskList.count() > 0: above_item = self.ui.listWidgetTaskList.takeItem(current_row - 1) self.ui.listWidgetTaskList.insertItem(current_row, above_item) @Slot() def TaskMoveDown(self): current_row = self.ui.listWidgetTaskList.currentRow() if current_row < self.ui.listWidgetTaskList.count() - 1 and self.ui.listWidgetTaskList.count() > 0: below_item = self.ui.listWidgetTaskList.takeItem(current_row + 1) self.ui.listWidgetTaskList.insertItem(current_row, below_item) @Slot() def OpenNewActionDialog(self): current_action_type = self.action_type_dict[self.ui.comboBoxActionType.currentText()] if current_action_type == self.action_type_dict["启动游戏"]: pass elif current_action_type == self.action_type_dict["释放游戏"]: pass elif current_action_type == self.action_type_dict["鼠标"]: self._new_mouse_action_dialog.OpenNewDialog() @Slot() def OpenEditActionDialog(self): currentItem = self.ui.listWidgetActionList.currentItem() action_data = currentItem.data(Qt.UserRole) if action_data._action_type == self.action_type_dict["鼠标"]: self._new_mouse_action_dialog.OpenEditDialog(action_data._mouse_action_data._mouse_action_type, action_data._mouse_action_data._timer) @Slot() def DeleteAction(self): current_row = self.ui.listWidgetActionList.currentRow() if self.ui.listWidgetActionList.count() > 0 and current_row >= 0: self.ui.listWidgetActionList.takeItem(current_row) self._render_area.rect_list.clear() self._render_area.update() @Slot() def ActionItemSelected(self): currentItem = self.ui.listWidgetActionList.currentItem() mouse_action_data = currentItem.data(Qt.UserRole)._mouse_action_data rect = Rect(QRect(mouse_action_data._x, mouse_action_data._y, mouse_action_data._width, mouse_action_data._height)) self._render_area.rect_list.clear() self._render_area.rect_list.append(rect) self._render_area.update() @Slot() def AddMouseAction(self, mouseactiondata): action_data = ActionData() action_data._action_type = self.action_type_dict["鼠标"] action_data._mouse_action_data = mouseactiondata item = QListWidgetItem() item.setText(mouseactiondata._mouse_action_name) item.setData(Qt.UserRole, action_data) self.ui.listWidgetActionList.addItem(item) #save self.SaveActionList() @Slot() def EditMouseAction(self, mouseactiondata): currentItem = self.ui.listWidgetActionList.currentItem() action_data = currentItem.data(Qt.UserRole) action_data._mouse_action_data._mouse_action_type = mouseactiondata._mouse_action_type action_data._mouse_action_data._mouse_action_name = mouseactiondata._mouse_action_name action_data._mouse_action_data._timer = mouseactiondata._timer currentItem.setData(Qt.UserRole, action_data) currentItem.setText(action_data._mouse_action_data._mouse_action_name) self.ui.listWidgetActionList.setCurrentItem(currentItem) @Slot() def ActionMoveUp(self): current_row = self.ui.listWidgetActionList.currentRow() if current_row > 0 and self.ui.listWidgetActionList.count() > 0: above_item = self.ui.listWidgetActionList.takeItem(current_row - 1) self.ui.listWidgetActionList.insertItem(current_row, above_item) @Slot() def ActionMoveDown(self): current_row = self.ui.listWidgetActionList.currentRow() if current_row < self.ui.listWidgetActionList.count() - 1 and self.ui.listWidgetActionList.count() > 0: below_item = self.ui.listWidgetActionList.takeItem(current_row + 1) self.ui.listWidgetActionList.insertItem(current_row, below_item) @Slot() def UpdateStatus(self, event: QMouseEvent): pos_x = int(event.position().x()) pos_y = int(event.position().y()) str_pos = f"X:{pos_x} Y:{pos_y}" self.ui.statusbar.showMessage(str_pos) # print(f"X:{pos_x}, Y:{pos_y}") @Slot() def SaveRect(self): if len(self._render_area.rect_list): currentItem = self.ui.listWidgetActionList.currentItem() action_data = currentItem.data(Qt.UserRole) rect = self._render_area.rect_list[0]._rect action_data._mouse_action_data._x = rect.x() action_data._mouse_action_data._y = rect.y() action_data._mouse_action_data._width = rect.width() action_data._mouse_action_data._height = rect.height() currentItem.setData(Qt.UserRole, action_data) self.ui.listWidgetActionList.setCurrentItem(currentItem) def SaveActionList(self): action_data_list = [] for row in range(self.ui.listWidgetActionList.count()): item = self.ui.listWidgetActionList.item(row) action_data_list.append(item) currenttask = self.ui.listWidgetTaskList.currentItem() currenttask.setData(Qt.UserRole, action_data_list) self.ui.listWidgetTaskList.setCurrentItem(currenttask) if __name__ == "__main__": app = QApplication(sys.argv) widget = MainWindow() widget.show() sys.exit(app.exec())
-
here is the thing
every single Task Item include Action list I use QlistWidgetItem[] to save it
if I clicked task item. the action view area well reload data from taskitem.data().
when task every single item has no action data when you switch task item the program well not crash.
when there is only one task item with action data won't crash
but when you switch the task item that had action item the program well crash.
# This Python file uses the following encoding: utf-8 import sys import copy from PySide6.QtCore import Signal, Slot, QRect, Qt, QPoint from PySide6.QtGui import QPalette, QColor, QMouseEvent, QPen, QPainter from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, 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 from datamanager import ActionData from newtaskdialog import NewTaskDialog from newmouseactiondialog import NewMouseActionDialog class Rect: def __init__(self, rect: QRect): self._rect = rect self._is_hover = False self._is_drag = False self._is_edge_drag = False class RenderArea(QWidget): signal_move_event = Signal(QMouseEvent) signal_release_event = Signal() def __init__(self, parent=None): super().__init__(parent) self.setMouseTracking(True) self._mouse_x = 0 self._mouse_y = 0 self._previous_mouse_pos = None # 初始绘图相关 self.pen = QPen(Qt.blue, 3) self.rect_list = [] def isRectIncludeMouse(self, mouse_pos: QPoint, rect: QRect): cursor_x = mouse_pos.x() cursor_y = mouse_pos.y() edge_weight = 8 if(cursor_x >= rect.x() and cursor_x <= rect.x() + rect.width() - edge_weight and cursor_y >= rect.y() and cursor_y <= rect.y() + rect.height() - edge_weight ): return True else: return False def isMouseOnRectEdge(self, mouse_pos: QPoint, rect: QRect): cursor_x = mouse_pos.x() cursor_y = mouse_pos.y() edge_weight = 8 if(cursor_x <= rect.x() + rect.width() and cursor_x > rect.x() + rect.width() - edge_weight and cursor_y <= rect.y() + rect.height() and cursor_y > rect.y() + rect.height() - edge_weight ): return True else: return False def mousePressEvent(self, event: QMouseEvent): self._previous_mouse_pos = event.position().toPoint() is_there_one_drag = False is_there_one_edge_drag = False for rect_index in range(len(self.rect_list)): if (self.isRectIncludeMouse(event.position().toPoint(), self.rect_list[rect_index]._rect) and not is_there_one_drag): self.rect_list[rect_index]._is_drag = True is_there_one_drag = True elif(self.isMouseOnRectEdge(event.position().toPoint(), self.rect_list[rect_index]._rect) and not is_there_one_edge_drag): self.rect_list[rect_index]._is_edge_drag = True is_there_one_edge_drag = True def mouseReleaseEvent(self, event: QMouseEvent): for rect_index in range(len(self.rect_list)): self.rect_list[rect_index]._is_drag = False self.rect_list[rect_index]._is_edge_drag = False self.signal_release_event.emit() def mouseMoveEvent(self, event: QMouseEvent): for rect_index in range(len(self.rect_list)): if self.rect_list[rect_index]._is_drag: new_rect_x = (event.position().x() - self._previous_mouse_pos.x()) + self.rect_list[rect_index]._rect.x() new_rect_y = (event.position().y() - self._previous_mouse_pos.y()) + self.rect_list[rect_index]._rect.y() if new_rect_x >= 0 and new_rect_x <= self.width(): self.rect_list[rect_index]._rect.moveTo(new_rect_x, self.rect_list[rect_index]._rect.y()) if new_rect_y >= 0 and new_rect_y <= self.height(): self.rect_list[rect_index]._rect.moveTo(self.rect_list[rect_index]._rect.x(), new_rect_y) self._previous_mouse_pos = event.position().toPoint() elif self.rect_list[rect_index]._is_edge_drag: new_rect_widght = (event.position().x() - self._previous_mouse_pos.x()) + self.rect_list[rect_index]._rect.width() new_rect_height = (event.position().y() - self._previous_mouse_pos.y()) + self.rect_list[rect_index]._rect.height() if new_rect_widght < 16: new_rect_widght = 16 if new_rect_height < 16: new_rect_height = 16 self.rect_list[rect_index]._rect.setWidth(new_rect_widght) self.rect_list[rect_index]._rect.setHeight(new_rect_height) self._previous_mouse_pos = event.position().toPoint() self.update() self.signal_move_event.emit(event) QWidget.mouseMoveEvent(self, event) def paintEvent(self, event): # 绘制一个矩形 with QPainter(self) as painter: painter.setPen(self.pen) for rect in self.rect_list: if rect._is_hover: painter.save() pen = QPen(Qt.red, 3) painter.setPen(pen) painter.drawRect(rect._rect) painter.restore() else: painter.drawRect(rect._rect) # 碰撞检查 # 拖动 class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # new action type dick self.action_type_dict = { "启动游戏": 0, "释放游戏": 1, "鼠标": 2, "键盘": 3, } # self.setMouseTracking(True) self._NewTaskDialog = NewTaskDialog() self._NewTaskDialog.hide() self._new_mouse_action_dialog = NewMouseActionDialog() self._new_mouse_action_dialog.hide() # 绘制区域初始化 self._render_area = RenderArea() # 设置背景颜色 back_ground_palette = QPalette() back_ground_palette.setColor(QPalette.Window, QColor(200, 200, 200)) self._render_area.setPalette(back_ground_palette) self._render_area.setAutoFillBackground(True) # 设置布局,加入父窗口 right_widget_layout = QHBoxLayout() right_widget_layout.addWidget(self._render_area) self.ui.widget_right.setLayout(right_widget_layout) # 新建 Task slot self.ui.pushButtonNewTask.clicked.connect(self.OpenNewTaskDialog) # 编辑 Task self.ui.listWidgetTaskList.itemDoubleClicked.connect(self.OpenEditTaskDialog) self.ui.listWidgetTaskList.itemClicked.connect(self.TaskItemSelected) # delete Task self.ui.pushButtonDeleteTask.clicked.connect(self.DeleteTask) # 添加或修改 Task slot self._NewTaskDialog.signal_add_clicked.connect(self.AddNewTask) self._NewTaskDialog.signal_edit_clicked.connect(self.EditTask) # Move up or Move Down Task slot self.ui.pushButtonTaskMoveUp.clicked.connect(self.TaskMoveUp) self.ui.pushButtonTaskMoveDown.clicked.connect(self.TaskMoveDown) # new action slot self.ui.pushButtonNewAction.clicked.connect(self.OpenNewActionDialog) self.ui.listWidgetActionList.itemDoubleClicked.connect(self.OpenEditActionDialog) self.ui.pushButtonDeleteAction.clicked.connect(self.DeleteAction) self.ui.listWidgetActionList.itemClicked.connect(self.ActionItemSelected) # new mouse action slot self._new_mouse_action_dialog.signal_add_confirm_clicked.connect(self.AddMouseAction) self._new_mouse_action_dialog.signal_edit_confirm_clicked.connect(self.EditMouseAction) # Move up and Move down action slot self.ui.pushButtonActionMoveUp.clicked.connect(self.ActionMoveUp) self.ui.pushButtonActionMoveDown.clicked.connect(self.ActionMoveDown) #update mouse position self._render_area.signal_move_event.connect(self.UpdateStatus) self._render_area.signal_release_event.connect(self.SaveRect) @Slot() def OpenNewTaskDialog(self): self._NewTaskDialog.OpenNewDialog() @Slot() def OpenEditTaskDialog(self): self._NewTaskDialog.OpenEditDialog(self.ui.listWidgetTaskList.currentItem().text()) @Slot() def TaskItemSelected(self): current_item = self.ui.listWidgetTaskList.currentItem() action_data_list = current_item.data(Qt.UserRole) for i in range(self.ui.listWidgetActionList.count()): self.ui.listWidgetActionList.takeItem(0) for action_data in action_data_list: self.ui.listWidgetActionList.addItem(action_data) @Slot() def DeleteTask(self): current_row = self.ui.listWidgetTaskList.currentRow() if self.ui.listWidgetTaskList.count() > 0 and current_row >= 0: self.ui.listWidgetTaskList.takeItem(current_row) @Slot() def AddNewTask(self, name: str): item = QListWidgetItem() item.setText(name) action_data_list: List[QListWidgetItem] = [] item.setData(Qt.UserRole, action_data_list) self.ui.listWidgetTaskList.addItem(item) @Slot() def EditTask(self, name: str): currenttask = self.ui.listWidgetTaskList.currentItem() currenttask.setText(name) self.ui.listWidgetTaskList.setCurrentItem(currenttask) @Slot() def TaskMoveUp(self): current_row = self.ui.listWidgetTaskList.currentRow() if current_row > 0 and self.ui.listWidgetTaskList.count() > 0: above_item = self.ui.listWidgetTaskList.takeItem(current_row - 1) self.ui.listWidgetTaskList.insertItem(current_row, above_item) @Slot() def TaskMoveDown(self): current_row = self.ui.listWidgetTaskList.currentRow() if current_row < self.ui.listWidgetTaskList.count() - 1 and self.ui.listWidgetTaskList.count() > 0: below_item = self.ui.listWidgetTaskList.takeItem(current_row + 1) self.ui.listWidgetTaskList.insertItem(current_row, below_item) @Slot() def OpenNewActionDialog(self): current_action_type = self.action_type_dict[self.ui.comboBoxActionType.currentText()] if current_action_type == self.action_type_dict["启动游戏"]: pass elif current_action_type == self.action_type_dict["释放游戏"]: pass elif current_action_type == self.action_type_dict["鼠标"]: self._new_mouse_action_dialog.OpenNewDialog() @Slot() def OpenEditActionDialog(self): currentItem = self.ui.listWidgetActionList.currentItem() action_data = currentItem.data(Qt.UserRole) if action_data._action_type == self.action_type_dict["鼠标"]: self._new_mouse_action_dialog.OpenEditDialog(action_data._mouse_action_data._mouse_action_type, action_data._mouse_action_data._timer) @Slot() def DeleteAction(self): current_row = self.ui.listWidgetActionList.currentRow() if self.ui.listWidgetActionList.count() > 0 and current_row >= 0: self.ui.listWidgetActionList.takeItem(current_row) self._render_area.rect_list.clear() self._render_area.update() @Slot() def ActionItemSelected(self): currentItem = self.ui.listWidgetActionList.currentItem() mouse_action_data = currentItem.data(Qt.UserRole)._mouse_action_data rect = Rect(QRect(mouse_action_data._x, mouse_action_data._y, mouse_action_data._width, mouse_action_data._height)) self._render_area.rect_list.clear() self._render_area.rect_list.append(rect) self._render_area.update() @Slot() def AddMouseAction(self, mouseactiondata): action_data = ActionData() action_data._action_type = self.action_type_dict["鼠标"] action_data._mouse_action_data = mouseactiondata item = QListWidgetItem() item.setText(mouseactiondata._mouse_action_name) item.setData(Qt.UserRole, action_data) self.ui.listWidgetActionList.addItem(item) #save self.SaveActionList() @Slot() def EditMouseAction(self, mouseactiondata): currentItem = self.ui.listWidgetActionList.currentItem() action_data = currentItem.data(Qt.UserRole) action_data._mouse_action_data._mouse_action_type = mouseactiondata._mouse_action_type action_data._mouse_action_data._mouse_action_name = mouseactiondata._mouse_action_name action_data._mouse_action_data._timer = mouseactiondata._timer currentItem.setData(Qt.UserRole, action_data) currentItem.setText(action_data._mouse_action_data._mouse_action_name) self.ui.listWidgetActionList.setCurrentItem(currentItem) @Slot() def ActionMoveUp(self): current_row = self.ui.listWidgetActionList.currentRow() if current_row > 0 and self.ui.listWidgetActionList.count() > 0: above_item = self.ui.listWidgetActionList.takeItem(current_row - 1) self.ui.listWidgetActionList.insertItem(current_row, above_item) @Slot() def ActionMoveDown(self): current_row = self.ui.listWidgetActionList.currentRow() if current_row < self.ui.listWidgetActionList.count() - 1 and self.ui.listWidgetActionList.count() > 0: below_item = self.ui.listWidgetActionList.takeItem(current_row + 1) self.ui.listWidgetActionList.insertItem(current_row, below_item) @Slot() def UpdateStatus(self, event: QMouseEvent): pos_x = int(event.position().x()) pos_y = int(event.position().y()) str_pos = f"X:{pos_x} Y:{pos_y}" self.ui.statusbar.showMessage(str_pos) # print(f"X:{pos_x}, Y:{pos_y}") @Slot() def SaveRect(self): if len(self._render_area.rect_list): currentItem = self.ui.listWidgetActionList.currentItem() action_data = currentItem.data(Qt.UserRole) rect = self._render_area.rect_list[0]._rect action_data._mouse_action_data._x = rect.x() action_data._mouse_action_data._y = rect.y() action_data._mouse_action_data._width = rect.width() action_data._mouse_action_data._height = rect.height() currentItem.setData(Qt.UserRole, action_data) self.ui.listWidgetActionList.setCurrentItem(currentItem) def SaveActionList(self): action_data_list = [] for row in range(self.ui.listWidgetActionList.count()): item = self.ui.listWidgetActionList.item(row) action_data_list.append(item) currenttask = self.ui.listWidgetTaskList.currentItem() currenttask.setData(Qt.UserRole, action_data_list) self.ui.listWidgetTaskList.setCurrentItem(currenttask) if __name__ == "__main__": app = QApplication(sys.argv) widget = MainWindow() widget.show() sys.exit(app.exec())
Hi,
Please provide a minimal runable script that shows your issue. As it is now, it's impossible to run because form.ui is not provided.
There's also quite a lot of code to read to determine what is going on that is not related to the issue at hand.
-
Hi,
Please provide a minimal runable script that shows your issue. As it is now, it's impossible to run because form.ui is not provided.
There's also quite a lot of code to read to determine what is going on that is not related to the issue at hand.
thx for reply
here is new code
# This Python file uses the following encoding: utf-8 import sys import copy from PySide6.QtCore import Signal, Slot, QRect, Qt, QPoint from PySide6.QtGui import QPalette, QColor, QMouseEvent, QPen, QPainter from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, 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 from datamanager import ActionData from newtaskdialog import NewTaskDialog from newmouseactiondialog import NewMouseActionDialog class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # new action type dick self.action_type_dict = { "启动游戏": 0, "释放游戏": 1, "鼠标": 2, "键盘": 3, } # self.setMouseTracking(True) self._NewTaskDialog = NewTaskDialog() self._NewTaskDialog.hide() self._new_mouse_action_dialog = NewMouseActionDialog() self._new_mouse_action_dialog.hide() # 绘制区域初始化 self._render_area = RenderArea() # 设置背景颜色 back_ground_palette = QPalette() back_ground_palette.setColor(QPalette.Window, QColor(200, 200, 200)) self._render_area.setPalette(back_ground_palette) self._render_area.setAutoFillBackground(True) # 设置布局,加入父窗口 right_widget_layout = QHBoxLayout() right_widget_layout.addWidget(self._render_area) self.ui.widget_right.setLayout(right_widget_layout) # 新建 Task slot self.ui.pushButtonNewTask.clicked.connect(self.OpenNewTaskDialog) # 编辑 Task self.ui.listWidgetTaskList.itemDoubleClicked.connect(self.OpenEditTaskDialog) self.ui.listWidgetTaskList.itemClicked.connect(self.TaskItemSelected) # delete Task self.ui.pushButtonDeleteTask.clicked.connect(self.DeleteTask) # 添加或修改 Task slot self._NewTaskDialog.signal_add_clicked.connect(self.AddNewTask) self._NewTaskDialog.signal_edit_clicked.connect(self.EditTask) # Move up or Move Down Task slot self.ui.pushButtonTaskMoveUp.clicked.connect(self.TaskMoveUp) self.ui.pushButtonTaskMoveDown.clicked.connect(self.TaskMoveDown) # new action slot self.ui.pushButtonNewAction.clicked.connect(self.OpenNewActionDialog) self.ui.listWidgetActionList.itemDoubleClicked.connect(self.OpenEditActionDialog) self.ui.pushButtonDeleteAction.clicked.connect(self.DeleteAction) self.ui.listWidgetActionList.itemClicked.connect(self.ActionItemSelected) # new mouse action slot self._new_mouse_action_dialog.signal_add_confirm_clicked.connect(self.AddMouseAction) self._new_mouse_action_dialog.signal_edit_confirm_clicked.connect(self.EditMouseAction) # Move up and Move down action slot self.ui.pushButtonActionMoveUp.clicked.connect(self.ActionMoveUp) self.ui.pushButtonActionMoveDown.clicked.connect(self.ActionMoveDown) #update mouse position self._render_area.signal_move_event.connect(self.UpdateStatus) self._render_area.signal_release_event.connect(self.SaveRect) # important this function lead to program crashed, if some task item selected this function well clear the action list and fill it up form selected task item data @Slot() def TaskItemSelected(self): current_item = self.ui.listWidgetTaskList.currentItem() action_data_list = current_item.data(Qt.UserRole) for i in range(self.ui.listWidgetActionList.count()): self.ui.listWidgetActionList.takeItem(0) for action_data in action_data_list: self.ui.listWidgetActionList.addItem(action_data) # add new task item @Slot() def AddNewTask(self, name: str): item = QListWidgetItem() item.setText(name) action_data_list: List[QListWidgetItem] = [] item.setData(Qt.UserRole, action_data_list) self.ui.listWidgetTaskList.addItem(item) # this function well add action item to the listwidget @Slot() def AddMouseAction(self, mouseactiondata): action_data = ActionData() action_data._action_type = self.action_type_dict["鼠标"] action_data._mouse_action_data = mouseactiondata item = QListWidgetItem() item.setText(mouseactiondata._mouse_action_name) item.setData(Qt.UserRole, action_data) self.ui.listWidgetActionList.addItem(item) # save action item(Qlistwidgetitem[]) to task item if some task item selected(call setData(qt.User, Qlistwidgetitem[])) self.SaveActionList() # save action item(Qlistwidgetitem[]) to task item if some task item selected(call setData(qt.User, Qlistwidgetitem[])) def SaveActionList(self): action_data_list = [] for row in range(self.ui.listWidgetActionList.count()): item = self.ui.listWidgetActionList.item(row) action_data_list.append(item) currenttask = self.ui.listWidgetTaskList.currentItem() currenttask.setData(Qt.UserRole, action_data_list) self.ui.listWidgetTaskList.setCurrentItem(currenttask) if __name__ == "__main__": app = QApplication(sys.argv) widget = MainWindow() widget.show() sys.exit(app.exec())
step one add task item and add three action item for it only one item no matter how much you click this task item the program won't crash
and step two add second task item and dont add any action item
step three when you selected first task item then boom my pragram already crashed
-
thx for reply
here is new code
# This Python file uses the following encoding: utf-8 import sys import copy from PySide6.QtCore import Signal, Slot, QRect, Qt, QPoint from PySide6.QtGui import QPalette, QColor, QMouseEvent, QPen, QPainter from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QHBoxLayout, 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 from datamanager import ActionData from newtaskdialog import NewTaskDialog from newmouseactiondialog import NewMouseActionDialog class MainWindow(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) # new action type dick self.action_type_dict = { "启动游戏": 0, "释放游戏": 1, "鼠标": 2, "键盘": 3, } # self.setMouseTracking(True) self._NewTaskDialog = NewTaskDialog() self._NewTaskDialog.hide() self._new_mouse_action_dialog = NewMouseActionDialog() self._new_mouse_action_dialog.hide() # 绘制区域初始化 self._render_area = RenderArea() # 设置背景颜色 back_ground_palette = QPalette() back_ground_palette.setColor(QPalette.Window, QColor(200, 200, 200)) self._render_area.setPalette(back_ground_palette) self._render_area.setAutoFillBackground(True) # 设置布局,加入父窗口 right_widget_layout = QHBoxLayout() right_widget_layout.addWidget(self._render_area) self.ui.widget_right.setLayout(right_widget_layout) # 新建 Task slot self.ui.pushButtonNewTask.clicked.connect(self.OpenNewTaskDialog) # 编辑 Task self.ui.listWidgetTaskList.itemDoubleClicked.connect(self.OpenEditTaskDialog) self.ui.listWidgetTaskList.itemClicked.connect(self.TaskItemSelected) # delete Task self.ui.pushButtonDeleteTask.clicked.connect(self.DeleteTask) # 添加或修改 Task slot self._NewTaskDialog.signal_add_clicked.connect(self.AddNewTask) self._NewTaskDialog.signal_edit_clicked.connect(self.EditTask) # Move up or Move Down Task slot self.ui.pushButtonTaskMoveUp.clicked.connect(self.TaskMoveUp) self.ui.pushButtonTaskMoveDown.clicked.connect(self.TaskMoveDown) # new action slot self.ui.pushButtonNewAction.clicked.connect(self.OpenNewActionDialog) self.ui.listWidgetActionList.itemDoubleClicked.connect(self.OpenEditActionDialog) self.ui.pushButtonDeleteAction.clicked.connect(self.DeleteAction) self.ui.listWidgetActionList.itemClicked.connect(self.ActionItemSelected) # new mouse action slot self._new_mouse_action_dialog.signal_add_confirm_clicked.connect(self.AddMouseAction) self._new_mouse_action_dialog.signal_edit_confirm_clicked.connect(self.EditMouseAction) # Move up and Move down action slot self.ui.pushButtonActionMoveUp.clicked.connect(self.ActionMoveUp) self.ui.pushButtonActionMoveDown.clicked.connect(self.ActionMoveDown) #update mouse position self._render_area.signal_move_event.connect(self.UpdateStatus) self._render_area.signal_release_event.connect(self.SaveRect) # important this function lead to program crashed, if some task item selected this function well clear the action list and fill it up form selected task item data @Slot() def TaskItemSelected(self): current_item = self.ui.listWidgetTaskList.currentItem() action_data_list = current_item.data(Qt.UserRole) for i in range(self.ui.listWidgetActionList.count()): self.ui.listWidgetActionList.takeItem(0) for action_data in action_data_list: self.ui.listWidgetActionList.addItem(action_data) # add new task item @Slot() def AddNewTask(self, name: str): item = QListWidgetItem() item.setText(name) action_data_list: List[QListWidgetItem] = [] item.setData(Qt.UserRole, action_data_list) self.ui.listWidgetTaskList.addItem(item) # this function well add action item to the listwidget @Slot() def AddMouseAction(self, mouseactiondata): action_data = ActionData() action_data._action_type = self.action_type_dict["鼠标"] action_data._mouse_action_data = mouseactiondata item = QListWidgetItem() item.setText(mouseactiondata._mouse_action_name) item.setData(Qt.UserRole, action_data) self.ui.listWidgetActionList.addItem(item) # save action item(Qlistwidgetitem[]) to task item if some task item selected(call setData(qt.User, Qlistwidgetitem[])) self.SaveActionList() # save action item(Qlistwidgetitem[]) to task item if some task item selected(call setData(qt.User, Qlistwidgetitem[])) def SaveActionList(self): action_data_list = [] for row in range(self.ui.listWidgetActionList.count()): item = self.ui.listWidgetActionList.item(row) action_data_list.append(item) currenttask = self.ui.listWidgetTaskList.currentItem() currenttask.setData(Qt.UserRole, action_data_list) self.ui.listWidgetTaskList.setCurrentItem(currenttask) if __name__ == "__main__": app = QApplication(sys.argv) widget = MainWindow() widget.show() sys.exit(app.exec())
step one add task item and add three action item for it only one item no matter how much you click this task item the program won't crash
and step two add second task item and dont add any action item
step three when you selected first task item then boom my pragram already crashed
@Daniel-Breeze this is a first step but still not runnable, neither form.ui is available nor any of the other imported custom classes.
-
@Daniel-Breeze this is a first step but still not runnable, neither form.ui is available nor any of the other imported custom classes.
@SGaist
thx, I wirte a simple version. this time well be easy to read# 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[QListWidgetItem] = [] action_data_list_2: List[QListWidgetItem] = [] action_data_list.append(QListWidgetItem("action 1")) action_data_list.append(QListWidgetItem("action 2")) self.ui.listWidget_2.addItem(action_data_list[0]) self.ui.listWidget_2.addItem(action_data_list[1]) 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())
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QListWidget" name="listWidget"> <property name="geometry"> <rect> <x>110</x> <y>170</y> <width>256</width> <height>192</height> </rect> </property> </widget> <widget class="QListWidget" name="listWidget_2"> <property name="geometry"> <rect> <x>440</x> <y>170</y> <width>256</width> <height>192</height> </rect> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>21</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
-
@SGaist
thx, I wirte a simple version. this time well be easy to read# 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[QListWidgetItem] = [] action_data_list_2: List[QListWidgetItem] = [] action_data_list.append(QListWidgetItem("action 1")) action_data_list.append(QListWidgetItem("action 2")) self.ui.listWidget_2.addItem(action_data_list[0]) self.ui.listWidget_2.addItem(action_data_list[1]) 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())
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QListWidget" name="listWidget"> <property name="geometry"> <rect> <x>110</x> <y>170</y> <width>256</width> <height>192</height> </rect> </property> </widget> <widget class="QListWidget" name="listWidget_2"> <property name="geometry"> <rect> <x>440</x> <y>170</y> <width>256</width> <height>192</height> </rect> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>21</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui>
@Daniel-Breeze
I have pasted your code into my Qt 15/PySide 2. It now looks like this:So what is the issue/supposed to go wrong? I can click any item, if I click in left-hand list then right-hand list changes, nothing goes wrong. Is that all I am supposed to do? Does it go wrong for you in PySide6?
-
@Daniel-Breeze
I have pasted your code into my Qt 15/PySide 2. It now looks like this:So what is the issue/supposed to go wrong? I can click any item, if I click in left-hand list then right-hand list changes, nothing goes wrong. Is that all I am supposed to do? Does it go wrong for you in PySide6?
@JonB
I try run it at pyside2. it work.but pyside6 still crashed.
when you select task 2 the right list well empty. then you select task 1 the action 1 and action 2 should be restore at right list. in pyside6 had crashed, but pyside2 work fine.
and I changed a few version of pysidee6 it also crashed, is that pyside6 bug?
JonB would you please try it in pyside6, I really wanna know whats going on here -
@JonB
I try run it at pyside2. it work.but pyside6 still crashed.
when you select task 2 the right list well empty. then you select task 1 the action 1 and action 2 should be restore at right list. in pyside6 had crashed, but pyside2 work fine.
and I changed a few version of pysidee6 it also crashed, is that pyside6 bug?
JonB would you please try it in pyside6, I really wanna know whats going on here@Daniel-Breeze
If I had PySide 6 you can be sure I would have tried it :) That's why I tried PySide 2. Yes, whatever it is must be a PySide 6 issue. -
-
@JonB
I try run it at pyside2. it work.but pyside6 still crashed.
when you select task 2 the right list well empty. then you select task 1 the action 1 and action 2 should be restore at right list. in pyside6 had crashed, but pyside2 work fine.
and I changed a few version of pysidee6 it also crashed, is that pyside6 bug?
JonB would you please try it in pyside6, I really wanna know whats going on here@Daniel-Breeze I would say that what you are doing is wrong. Your
action_data_list
contains QListWidgetItem objects. Objects that you remove and add to your other view. When you call takeItem, you "extract" the item from the view and thus become responsible for its lifetime management again (thus your call to clean are technically useless). Since you don't do anything with them, they get garbage collected, so next time you try to make use of them, you in fact will be using delete objects hence your crash.One could wonder why the fact they are stored as custom data in listWidget items does not keep the reference, that might be the central point.
Anyway, since your items only contain strings, you should rather store a list of them as UserRole data and you can them simply call clean on your QListWidget objects. Then use addItems with the string list to recreate the content of listWidget_2.
-
@Daniel-Breeze I would say that what you are doing is wrong. Your
action_data_list
contains QListWidgetItem objects. Objects that you remove and add to your other view. When you call takeItem, you "extract" the item from the view and thus become responsible for its lifetime management again (thus your call to clean are technically useless). Since you don't do anything with them, they get garbage collected, so next time you try to make use of them, you in fact will be using delete objects hence your crash.One could wonder why the fact they are stored as custom data in listWidget items does not keep the reference, that might be the central point.
Anyway, since your items only contain strings, you should rather store a list of them as UserRole data and you can them simply call clean on your QListWidget objects. Then use addItems with the string list to recreate the content of listWidget_2.
@SGaist
thx, I just Simplified my code here it is I didn't call any of remove item function when you select that item the program well direct crash.# This Python file uses the following encoding: utf-8 import sys from PySide6.QtCore import Qt import PySide6.QtCore 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) print(PySide6.QtCore.__version__) self._previous_item = None item1 = QListWidgetItem("task 1") self.ui.listWidget.addItem(item1) action_data_list: list[QListWidgetItem] = [] action_data_list.append(QListWidgetItem("action 1")) action_data_list.append(QListWidgetItem("action 2")) item1.setData(Qt.UserRole, action_data_list) self.ui.listWidget.itemClicked.connect(self.reload) # reload item to listWidget_2 def reload(self): action_data_list = self.ui.listWidget.item(0).data(Qt.UserRole) 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())
you mean when init function after excuted, the action_data_list are already deleted?
-
@SGaist
thx, I just Simplified my code here it is I didn't call any of remove item function when you select that item the program well direct crash.# This Python file uses the following encoding: utf-8 import sys from PySide6.QtCore import Qt import PySide6.QtCore 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) print(PySide6.QtCore.__version__) self._previous_item = None item1 = QListWidgetItem("task 1") self.ui.listWidget.addItem(item1) action_data_list: list[QListWidgetItem] = [] action_data_list.append(QListWidgetItem("action 1")) action_data_list.append(QListWidgetItem("action 2")) item1.setData(Qt.UserRole, action_data_list) self.ui.listWidget.itemClicked.connect(self.reload) # reload item to listWidget_2 def reload(self): action_data_list = self.ui.listWidget.item(0).data(Qt.UserRole) 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())
you mean when init function after excuted, the action_data_list are already deleted?
@Daniel-Breeze said in need help about QlistWidget.data() problem(crashed without noticed):
the program well direct crash
Where exactly? What does debugger say?
-
@Daniel-Breeze said in need help about QlistWidget.data() problem(crashed without noticed):
the program well direct crash
Where exactly? What does debugger say?
debugger say nothing
u can create window UI project choose pyside6 and mainwindow, add a listwidget in UI designer, copy my last code in your mainwindow.py run program click task 1. then program crashI think the problem is .data(Qt.UserRole) , if I # it. every seem okay
-
debugger say nothing
u can create window UI project choose pyside6 and mainwindow, add a listwidget in UI designer, copy my last code in your mainwindow.py run program click task 1. then program crashI think the problem is .data(Qt.UserRole) , if I # it. every seem okay
@Daniel-Breeze
The following is what I would try if I wanted either to find a workaround or report as a PySide6 bug:- Move the
self.ui.listWidget.addItem(item1)
to after theitem1.setData(Qt.UserRole, action_data_list)
. It should make no difference, but just in case. - Put
print()
statements intodef reload()
. Does it "die" onaction_data_list = self.ui.listWidget.item(0).data(Qt.UserRole)
or on thefor action_data in action_data_list
? - Make sure
self.ui.listWidget.item(0)
on its own accesses the item without "dying". - Change
Qt.UserRole
toQt.DisplayRole
(forget about youraction_data_list
), make sure that works. - Try using
Qt.UserRole + 100
just in case. - You are marshalling a Python
list
, and a list ofQListWidgetItem
at that, across QtQVariant
(data()
) boundaries. Try (a) just a plain string/number then (b) a simple Pythonlist
of strings/numbers. Do either of those work OK? - If (b) works, as your code stands you do not need to store
QListWidgetItem
s (and worry about their possible ownership), you might as well just store strings.
Those are a start :)
- Move the
-
@Daniel-Breeze said in need help about QlistWidget.data() problem(crashed without noticed):
the program well direct crash
Where exactly? What does debugger say?
@jsulm It's not a python crash, it's a C++ crash.
It happens because the application tries to access already freed resources.
On the technical side, I think that there's something that might be off with Python/C++ memory management at play. Technically, the items are stored in a temporary list which itself is then stored in an item. That should make it not temporary anymore and thus keep a reference to the items. However, it looks like it does not work that way. It might be due to the nature of the objects stored there.
That said, the simple fix in this case is to use a list of strings rather than a list of QListWidgetItem. You can then leverage the addItems function so you have one less loop in your code.