Search code examples
pythonpyqt5qtablewidgetqcombobox

Trying to retrieve QcomboBox selection from with QtableWidget


I have a function that inserts multiple QcomboBoxes in the first row of QtableWidget and then updates an excel file starting in row 2. This is at the end of my function:

    for i in range(df.shape[1]):
        combo = comboCompanies(self)
        self.tableWidget.setCellWidget(0, i, combo)

What I would like to do is know when one of the indexes is changed on a combobox but they currently have the same name so I need to figure out how to uniquely identity them. I found the following but it isnt in Python

        QComboBox* myComboBox = new QComboBox(); // making a new dropdown box
        myComboBox->setObjectName(QString::number(i)); // pass column number as object name
        connect(myComboBox, SIGNAL(currentIndexChanged(QString)), 
        SLOT(onComboChanged(QString)));
        ui->tableWidget->setCellWidget(0,i,myComboBox); // put box into table

How do I code in Python?


Solution

  • You can identify Your Combobox eihter by setting it's objectname or just by passing it's column as a parameter to the callback.

    currentIndexChanged signal only gives You new changed index, but not the Combobox itself. That's why we have to use inline lambda function.

    Here is the code with both options used:

    import sys
    
    from PyQt5.QtWidgets import QApplication, QTableWidget, QComboBox
    
    
    def index_changed_id_by_column(column: int, selected_index: int) -> None:
        """combobox in column changed selected_index"""
        print(f"Combobox in column: {column}, changed to index:{selected_index}")
    
    
    def index_changed_id_by_combobox(combobox: QComboBox, selected_index: int) -> None:
        """combobox changed selected_index"""
        print(f"Combobox: {combobox.objectName()}, changed to index:{selected_index}")
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    
        # Create some Table
        table = QTableWidget()
        table.setRowCount(2)
        table.setColumnCount(4)
    
        # Solution 1, using column index to identify Combobox
        for i in range(table.columnCount()):
            combobox = QComboBox()
            combobox.addItems(["Option 1", "Option 2", "Option 3"])
            '''
            This connects currentIndexChanged signal with lambda function (selected_index, column), 
            calling index_changed_id_by_column slot
            '''
            combobox.currentIndexChanged.connect(
                lambda selected_index, column=i: index_changed_id_by_column(column, selected_index))
            table.setCellWidget(0, i, combobox)
    
        # Solution 2, using objectName to identify Combobox
        for i in range(table.columnCount()):
            combobox = QComboBox()
            combobox.setObjectName(f"combobox_row1_coll{i}")
            combobox.addItems(["Option 1", "Option 2", "Option 3"])
            '''
            This connects currentIndexChanged signal with lambda function (selected_index, combobox), 
            calling index_changed_id_by_combobox slot
            '''
            combobox.currentIndexChanged.connect(
                lambda selected_index, combobox=combobox: index_changed_id_by_combobox(combobox, selected_index))
            table.setCellWidget(1, i, combobox)
    
        table.show()
    
        app.exec()
    

    In first row we have Comboboxes calling index_changed_id_by_column callback.
    In second row Comboboxes calling index_changed_id_by_combobox callback.

    Pick the one that You need for Your project.