Search code examples
pythonpyqt5qlistwidget

QListWidget: currentRowChanged rollback


def selected_radio_connection_changed(self,current_row):
    self.current_row_new = self.main_self.ui_edit_radio_stations_window.stations_list.currentRow()
    
    if(self.current_row_new!=self.current_row):
        #ask for saving
        box = QMessageBox()
        box.setIcon(QMessageBox.Question)
        box.setWindowTitle('Αποθήκευση αλλαγών')
        box.setText('Θέλετε να αποθηκεύσετε τις αλλαγές σας;')
        box.setStandardButtons(QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel)
        buttonY = box.button(QMessageBox.Yes)
        buttonY.setText('Ναι')
        buttonN = box.button(QMessageBox.No)
        buttonN.setText('Οχι')
        buttonC = box.button(QMessageBox.Cancel)
        buttonC.setText('Ακύρωση')
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(":/menu_window_icons/media/images/save.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        box.setWindowIcon(icon)
        box.exec_()
        if box.clickedButton() == buttonY:
            self.save()
            self.current_row = self.current_row_new
            self.main_self.ui_edit_radio_stations_window.stations_list.setCurrentRow(self.current_row)
            self.show_radio_connection_details()
        elif box.clickedButton() == buttonN:
            self.current_row = self.current_row_new
            self.main_self.ui_edit_radio_stations_window.stations_list.setCurrentRow(self.current_row)
            self.show_radio_connection_details()
        elif box.clickedButton() == buttonC:
            self.previous_item_timer=QTimer()
            self.previous_item_timer.timeout.connect(self.return_to_previous_list_item)
            self.previous_item_timer.setSingleShot(True)
            self.previous_item_timer.start(100)
            
def return_to_previous_list_item(self):
    self.main_self.ui_edit_radio_stations_window.stations_list.setCurrentRow(self.current_row)
    self.current_row = self.main_self.ui_edit_radio_stations_window.stations_list.currentRow()

The first method is called: with this command:

self.main_self.ui_edit_radio_stations_window.stations_list.currentRowChanged.connect(lambda current_row:self.selected_radio_connection_changed(current_row))

where stations_list is a QListWidget.

Every time the current qlist-item is change, then A QMessageBox prompt is opened.

With the first two buttons everything seems to be ok. But when the third, is clicked then i want to rollback to the previous qlist-item.

The question is: Why a QTimer is needed for this operation?

I suppose that there is an event.accept() after the call of selected_radio_connection_changed method.


Solution

  • The problem comes from the fact that you're trying to "override" the current index within a current index change. You should be more careful about that, as such interactions might lead to recursion problems.

    An important thing to always consider is that the current index of a model view doesn't always match the selection.

    Setting a current index should happen at the end of a "current change", so you can safely use a QTimer or use the view's selection model selectionChanged signal instead.

    Unfortunately, you didn't provide a clear enough MRE, so it's hard to give you a more specific solution, it depends on your needs and how you're implementing the whole procedure.