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. Update selected Item(index) after InternalMove in listview
QtWS25 Last Chance

Update selected Item(index) after InternalMove in listview

Scheduled Pinned Locked Moved Unsolved Qt for Python
2 Posts 1 Posters 592 Views
  • 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.
  • alomA Offline
    alomA Offline
    alom
    wrote on last edited by alom
    #1

    I have two listviews, the left shows parent items and the right it's parents children.
    I would like the the children to be able to be rearranged with setDragDropMode(QAbstractItemView.InternalMove). This seems to work as expected. The issue is if I have an item selected and move it, the original row still stays selected. How can I update the moved index to the listview current item? I would expect the selection to move with the InternalMove behavoir.

    I've tried to implement the dropEvent() on the listview, but that was causing duplicate items. when I was using setCurrentIndex().

    I tried to catch the insertedRow signal and try the same thing with similar results. I guess I dont fully understand selections yet. I see the listview has a selectionModel, i have tried to something like
    self.selectionModel().setCurrentIndex(index, QtCore.QItemSelectionModel.Select)
    same results.

    Any help greatly appreciated!

    import sys
    from PySide2.QtCore import Qt, QSize
    from PySide2.QtWidgets import QMainWindow, QApplication, QStyledItemDelegate, QListView, QHBoxLayout, QWidget, QAbstractItemView,QStyle
    from PySide2.QtGui import QStandardItemModel, QStandardItem, QColor, QFont, QFontMetrics
    
    
    
    class CustomDelegate(QStyledItemDelegate):
        def __init__(self, parent=None):
            super(CustomDelegate, self).__init__(parent)
            self.text_title = QColor(109, 210, 240)
            self.text_description = QColor(120, 120, 120)
            self.cell_default = QColor(250, 250, 250)
    
    
        def paint(self, painter, option, index):
            current_item = index.model().itemFromIndex(index)
            value = current_item.text()
            x = option.rect.x()
            y = option.rect.y()
            h = option.rect.height()
            w = option.rect.width()
            painter.save()
            if option.state & QStyle.State_Selected:
                painter.fillRect(option.rect, self.text_description)
                painter.drawText(x+2, y+h-4, value)
    
            elif option.state & QStyle.State_MouseOver:
                painter.fillRect(option.rect, self.text_title)
                painter.drawText(x + 2, y + h -4 , value)
    
            else:
                QStyledItemDelegate.paint(self, painter, option, index)
    
            painter.restore()
    
    
    class MainWindow(QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.task_grp_view = QListView(self)
            self.task_view = QListView(self)
            self.task_view.setDragDropMode(QAbstractItemView.InternalMove)
            self.model = QStandardItemModel(self)
            self.task_grp_view.setModel(self.model)
            self.task_view.setModel(self.model)
            self.task_view.setItemDelegate(CustomDelegate())
            self.h_layout = QHBoxLayout(self)
            self.h_layout.addWidget(self.task_grp_view)
            self.h_layout.addWidget(self.task_view)
            self.cw = QWidget(self)
            self.cw.setLayout(self.h_layout)
            self.setCentralWidget(self.cw)
    
            self.task_grp_view.model().dataChanged.connect(self.update_user_data)
            self.task_grp_view.pressed.connect(self.update_task_view)
    
            self.populate_model()
    
        def populate_model(self):
            stuff = ['zero', 'one', 'two']
            for i, s in enumerate(stuff):
                item = QStandardItem(s)
                for sub in stuff:
                    sub_item = QStandardItem(str(i) + '_' + sub)
                    sub_item.setDropEnabled(False)
                    item.appendRow(sub_item)
                self.model.appendRow(item)
            self.task_grp_view.setCurrentIndex(self.model.index(0, 0))
            self.task_view.setRootIndex(self.task_grp_view.currentIndex())
    
        def update_task_view(self, index):
            self.task_view.setRootIndex(index)
    
        def update_user_data(self):
            pass
            # print('called')
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
        sys.exit(app.exec_())
    
    1 Reply Last reply
    0
    • alomA Offline
      alomA Offline
      alom
      wrote on last edited by
      #2

      Hmm... im still a bit lost here.
      I've been trying to catch a signal from the view and the selection model after the interalMove.
      the signals from:
      task_view.selectionModel().currentRowChanged
      self.modelmodel.rowsInserted

      both give me a start and end index or to and from ints, but if I call the rowCount() on the parent item it returns one additional NULL row for the children. I'm thinking this is the model in the process of inserting a new row and hasn't updated yet. Regardless I cant seem to use the task_view selection Model to select the index (maybe its invalid?), the selection just stays on the row where the drag started.

      I'm just not sure where to grab the internalMove data and update AFTER the model sorts its self out.

      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