title: Dependent QComboBoxes in a QTableWidget
body: <p>I am trying to link 3 different comboboxes in Pyqt5 inside a qtablewidget. the first 2 are linked in one slot and the third one is linked to the second combobox using a different slot in a separate definition. On the change of the first combobox, the 2nd combobox changes which makes the 3rd one change (similar to car selection websites).</p>
  
  <p>The current issue is that on change of the first combobox the second signal also executes which makes it execute twice and giving me dictionary key error as the first execution doesnt include the key. The error occurs on Line 81 when trying to access the dictionary.
  See the image as it runs the index twice:</p>
  
  <p><a href="https://i.stack.imgur.com/jB8gZ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/jB8gZ.png" alt="enter image description here"></a></p>
  
  <p><strong>Attempt</strong></p>
  
  <pre><code>from PyQt5 import QtCore, QtGui, QtWidgets
  from PyQt5.QtWidgets import QMessageBox, QMainWindow, QApplication, QFileDialog
  
  
  class MainWindow(QtWidgets.QMainWindow):
      def __init__(self, parent=None):
          super(MainWindow, self).__init__(parent)
  
          self.m_tablewidget = QtWidgets.QTableWidget(0, 3)
          self.m_tablewidget.setHorizontalHeaderLabels(
              ["Col 1", "Col 2", "Col 3"]
          )
          self.m_button = QtWidgets.QPushButton("Add Row", clicked=self.onClicked)
  
          central_widget = QtWidgets.QWidget()
          self.setCentralWidget(central_widget)
          lay = QtWidgets.QVBoxLayout(central_widget)
          lay.addWidget(self.m_tablewidget)
          lay.addWidget(self.m_button, alignment=QtCore.Qt.AlignLeft)
          self.vehicleHardware_dict = {'k': ['LiftSource_Wing_ChordConstantChordTapered', 'TPS_Active_Coolant'], 'X51': ['TPS_Passive_Tile', 'ThrustSource_Airbreathing_ScramjetTwoD']}
          self.procesVeh_dict = {'k': ['Aerodynamics', 'Optimization', 'Propulsion', 'Weight_Balance'], 'X51': ['Aerodynamics', 'Optimization', 'Propulsion', 'Weight_Balance']}
          self.processMethod_dict = {'Aerodynamics': ['kia', 'T1_case2_outNoIn'], 'Optimization': ['thomas'], 'Propulsion': ['test', 'rocket', 'T1_case3_InOutSame_inLess'], 'Weight_Balance': ['wing weight', 'T1_case1_inNoOut', 'T1_case3_inOutEq_inMore']}
          self.methodInput_dict = {'T1_case1_inNoOut': ['T'], 'T1_case2_outNoIn': [], 'T1_case3_InOutSame_inLess': ['T'], 'T1_case3_inOutEq_inMore': ['THRUST_REF'], 'kia': ['ACS', 'AEXIT', 'AE_AT', 'AIP', 'AISP', 'AISP_AVAIL_V', 'AISP_EFF', 'AISP_EFF_V', 'THETA2_N'], 'rocket': ['AIP', 'AISP', 'AISP_AVAIL_V', 'AISP_EFF', 'AISP_EFF_V', 'AISP_HW', 'AISP_REF'], 'test': ['ACS', 'Y_V'], 'thomas': ['ACS', 'AEXIT', 'AE_AT', 'AIP', 'AISP', 'AISP_AVAIL_V', 'CS', 'DIA_BODY'], 'wing weight': ['A', 'ABASE', 'ACAP', 'ACAP_SPLN', 'ACS', 'AEXIT', 'AE_AT']}
  
      @QtCore.pyqtSlot()
      def onClicked(self):
          combobox1_vehicle = QtWidgets.QComboBox()
          combobox2_hardware = QtWidgets.QComboBox()
          # combo_dummy = QtWidgets.QComboBox()
          for k, v in self.processMethod_dict.items():
              combobox1_vehicle.addItem(k, v)
              for kk, vv in self.methodInput_dict.items():
                  combobox2_hardware.addItem(kk, vv)
  
          combobox3 = QtWidgets.QComboBox()
          combobox3.addItems(combobox2_hardware.currentData())
  
          combobox1_vehicle.currentIndexChanged.connect(self.onCurrentTextChanged1)
          combobox2_hardware.currentIndexChanged.connect(self.onCurrentTextChanged2)
  
          rc = self.m_tablewidget.rowCount()
          self.m_tablewidget.insertRow(rc)
  
          for i, combo in enumerate((combobox1_vehicle, combobox2_hardware, combobox3)):
              self.m_tablewidget.setCellWidget(rc, i, combo)
  
      @QtCore.pyqtSlot()
      def onCurrentTextChanged1(self):
          combobox1_vehicle = self.sender()
          if not isinstance(combobox1_vehicle, QtWidgets.QComboBox):
              return
          p = combobox1_vehicle.mapTo(self.m_tablewidget.viewport(), QtCore.QPoint())
          ix = self.m_tablewidget.indexAt(p)
          if not ix.isValid() or ix.column() != 0:
              return
          r = ix.row()
          data = combobox1_vehicle.currentData()
          combobox2_hardware = self.m_tablewidget.cellWidget(r, 1)
          if not isinstance(combobox2_hardware, QtWidgets.QComboBox):
              return
          combobox2_hardware.clear()
          combobox2_hardware.addItems(data)
  
  
      @QtCore.pyqtSlot()
      def onCurrentTextChanged2(self):
          combobox2_hardware = self.sender()
          if not isinstance(combobox2_hardware, QtWidgets.QComboBox):
              return
          p = combobox2_hardware.mapTo(self.m_tablewidget.viewport(), QtCore.QPoint())
          ix = self.m_tablewidget.indexAt(p)
          if not ix.isValid() or ix.column() != 1:
              return
          r = ix.row()
          # data = combobox2_hardware.currentData()
          valueOfKey = combobox2_hardware.currentText()
          print(combobox2_hardware)
          print(p)
          print(ix)
  
          data = self.methodInput_dict[valueOfKey]
          combobox3 = self.m_tablewidget.cellWidget(r, 2)
          if not isinstance(combobox3, QtWidgets.QComboBox):
              return
          combobox3.clear()
          if data == None:
              combobox3.addItem("")
          else:
              combobox3.addItems(data)
  
  
  
  if __name__ == "__main__":
      import sys
  
      app = QtWidgets.QApplication(sys.argv)
  
      w = MainWindow()
      w.resize(640, 480)
      w.show()
      sys.exit(app.exec_())
  </code></pre>