Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. need help about QlistWidget.data() problem(crashed without noticed)
Forum Updated to NodeBB v4.3 + New Features

need help about QlistWidget.data() problem(crashed without noticed)

Scheduled Pinned Locked Moved Solved Qt for Python
14 Posts 4 Posters 1.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Daniel Breeze
    wrote on last edited by
    #1

    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.
    123.jpg

    # 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())
    
    
    SGaistS 1 Reply Last reply
    0
    • D Daniel Breeze

      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.
      123.jpg

      # 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())
      
      
      SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      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.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      D 1 Reply Last reply
      0
      • SGaistS SGaist

        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.

        D Offline
        D Offline
        Daniel Breeze
        wrote on last edited by
        #3

        @SGaist

        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())
        
        

        123431.jpg

        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
        321.jpg
        and step two add second task item and dont add any action item
        123333.jpg
        step three when you selected first task item then boom my pragram already crashed
        32452315.jpg

        SGaistS 1 Reply Last reply
        0
        • D Daniel Breeze

          @SGaist

          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())
          
          

          123431.jpg

          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
          321.jpg
          and step two add second task item and dont add any action item
          123333.jpg
          step three when you selected first task item then boom my pragram already crashed
          32452315.jpg

          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Daniel-Breeze this is a first step but still not runnable, neither form.ui is available nor any of the other imported custom classes.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          D 1 Reply Last reply
          0
          • SGaistS SGaist

            @Daniel-Breeze this is a first step but still not runnable, neither form.ui is available nor any of the other imported custom classes.

            D Offline
            D Offline
            Daniel Breeze
            wrote on last edited by
            #5

            @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>
            
            
            JonBJ 1 Reply Last reply
            0
            • D Daniel Breeze

              @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>
              
              
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @Daniel-Breeze
              I have pasted your code into my Qt 15/PySide 2. It now looks like this:

              e24d90c7-6bc2-46d3-9780-d5f77c92ee27-image.png

              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?

              D 1 Reply Last reply
              0
              • JonBJ JonB

                @Daniel-Breeze
                I have pasted your code into my Qt 15/PySide 2. It now looks like this:

                e24d90c7-6bc2-46d3-9780-d5f77c92ee27-image.png

                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?

                D Offline
                D Offline
                Daniel Breeze
                wrote on last edited by
                #7

                @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

                JonBJ SGaistS 2 Replies Last reply
                0
                • D Daniel Breeze

                  @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

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by
                  #8

                  @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.

                  1 Reply Last reply
                  0
                  • D Daniel Breeze has marked this topic as solved on
                  • D Daniel Breeze

                    @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

                    SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #9

                    @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.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    D 1 Reply Last reply
                    1
                    • SGaistS SGaist

                      @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.

                      D Offline
                      D Offline
                      Daniel Breeze
                      wrote on last edited by Daniel Breeze
                      #10

                      @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?

                      jsulmJ 1 Reply Last reply
                      0
                      • D Daniel Breeze

                        @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?

                        jsulmJ Offline
                        jsulmJ Offline
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @Daniel-Breeze said in need help about QlistWidget.data() problem(crashed without noticed):

                        the program well direct crash

                        Where exactly? What does debugger say?

                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                        D SGaistS 2 Replies Last reply
                        0
                        • jsulmJ jsulm

                          @Daniel-Breeze said in need help about QlistWidget.data() problem(crashed without noticed):

                          the program well direct crash

                          Where exactly? What does debugger say?

                          D Offline
                          D Offline
                          Daniel Breeze
                          wrote on last edited by Daniel Breeze
                          #12

                          @jsulm

                          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 crash

                          I think the problem is .data(Qt.UserRole) , if I # it. every seem okay

                          JonBJ 1 Reply Last reply
                          0
                          • D Daniel Breeze

                            @jsulm

                            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 crash

                            I think the problem is .data(Qt.UserRole) , if I # it. every seem okay

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by JonB
                            #13

                            @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 the item1.setData(Qt.UserRole, action_data_list). It should make no difference, but just in case.
                            • Put print() statements into def reload(). Does it "die" on action_data_list = self.ui.listWidget.item(0).data(Qt.UserRole) or on the for action_data in action_data_list?
                            • Make sure self.ui.listWidget.item(0) on its own accesses the item without "dying".
                            • Change Qt.UserRole to Qt.DisplayRole (forget about your action_data_list), make sure that works.
                            • Try using Qt.UserRole + 100 just in case.
                            • You are marshalling a Python list, and a list of QListWidgetItem at that, across Qt QVariant (data()) boundaries. Try (a) just a plain string/number then (b) a simple Python list of strings/numbers. Do either of those work OK?
                            • If (b) works, as your code stands you do not need to store QListWidgetItems (and worry about their possible ownership), you might as well just store strings.

                            Those are a start :)

                            1 Reply Last reply
                            0
                            • jsulmJ jsulm

                              @Daniel-Breeze said in need help about QlistWidget.data() problem(crashed without noticed):

                              the program well direct crash

                              Where exactly? What does debugger say?

                              SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @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.

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved