Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-103007

Resetting a QComboBox custom model doesn't emit currentIndexChanged or currentTextChanged

    XMLWordPrintable

Details

    • Linux/X11, Windows
    • 662184ac68 (qt/qtbase/dev) a9a48466a1 (qt/qtbase/6.4) a9a48466a1 (qt/tqtc-qtbase/6.4) 51d0a76a62 (qt/qtbase/6.3) 51d0a76a62 (qt/tqtc-qtbase/6.3) 8a22b8add7 (qt/tqtc-qtbase/6.2)

    Description

      If a QComboBox has a currentIndex >= 0, then calling QComboBox.clear() will cause currentIndexChanged and currentTextChanged to be emitted since the currentIndex will be changed to -1. However, these signals are not emitted when clearing a custom model attached to a combo box. For example (using PySide):

      from PySide6 import QtWidgets, QtCore
      app = QtWidgets.QApplication([])
      combo = QtWidgets.QComboBox()
      combo.addItems(["a", "b", "c"])
      combo.setCurrentIndex(1)
      
      def on_current_index_changed(new_index):
          print(f"current index changed: {new_index}")
      
      combo.currentIndexChanged.connect(on_current_index_changed)
      combo.clear()
      

      will print "current index changed: -1" to standard out, but

      from PySide6 import QtWidgets, QtCore
      app = QtWidgets.QApplication([])
      combo = QtWidgets.QComboBox()
      model = QtCore.QStringListModel()
      combo.setModel(model)
      model.setStringList(["a", "b", "c"])
      combo.setCurrentIndex(1)
      
      def on_current_index_changed(new_index):
          print(f"current index changed: {new_index}")
      
      combo.currentIndexChanged.connect(on_current_index_changed)
      model.setStringList([])
      

      won't print anything. The same issue occurs when using currentTextChanged in place of currentIndexChanged. I see this behavior using Qt 6.3 as well as 6.2.2. (For Qt 6.3, PySide6.__version__, QtCore.__version__, and QtCore.qVersion() are all '6.3.0'. For Qt 6.2.2, PySide6.__version__ is '6.2.2.1', and QtCore.__version__ and QtCore.qVersion() are both '6.2.2'.) I've also seen the same behavior using PyQt with Qt 6.2.1, and I suspect the issue would occur in C++ as well. I don't see this behavior using PyQt with Qt 5.12. In that case, both scripts print out "current index changed: -1". I suspect the issue was introduced in QTBUG-80998. In Qt 5.12, QComboBoxPrivate::_q_modelReset had an explicit check to emit currentIndexChanged, but the current implementation relies on trySetValidIndex to emit currentIndexChanged, and it appears that method won't emit the signal if count() == 0 and currentIndex() == -1 since it can't set a valid index.

      Attachments

        Activity

          People

            ivan.solovev Ivan Solovev
            kevkeating Kevin Keating
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: