Search code examples
pythonpyqtsignals-slotsqtablewidgetqcombobox

PyQt5: get index of cell widgets and their chosen values


I am using Python 3.5, and I have a simple code which creates a table with a few combo-boxes inside of it. Here is the code:

from PyQt5 import QtCore
from PyQt5 import QtWidgets
import sys

app = QtWidgets.QApplication(sys.argv)

########################## Create table ##############################
tableWidget = QtWidgets.QTableWidget()
tableWidget.setGeometry(QtCore.QRect(200, 200, 250, 300))
tableWidget.setColumnCount(2)
tableWidget.setRowCount(9)
tableWidget.show()

################# Create tablecontent & comboboxes ###################
names = ['Name 1', 'Name 2', 'Name 3', 'Name 4']
i = 0
for j in names:
    tableWidget.setItem(i, 0, QtWidgets.QTableWidgetItem(j))

    comboBox = QtWidgets.QComboBox()
    combo_option_list = ["Choose...", "Option 1", "Option 2", "Option 3", "Option 4"]
    for t in combo_option_list:
        comboBox.addItem(t)

    tableWidget.setCellWidget(i, 1, comboBox)
    i += 1

sys.exit(app.exec_()) 

I want to work with these combo-boxes, but I have several problems. It already starts with the fact that I can only use the last created combo-box with the following command:

comboBox.activated[str].connect(do_something)

I need to know the following things:

  • How to connect signals for all the combo-boxes?
  • How to get the index of the selected combo-box?
  • How to get the index of the selected combo-box option after it was chosen?

Solution

  • Description below code

    from PyQt5 import QtCore
    from PyQt5 import QtWidgets
    import sys
    
    app = QtWidgets.QApplication(sys.argv)
    
    ########################## Create table ##############################
    
    tableWidget = QtWidgets.QTableWidget()
    tableWidget.setGeometry(QtCore.QRect(200, 200, 250, 300))
    tableWidget.setColumnCount(2)
    tableWidget.setRowCount(9)
    tableWidget.show()
    
    ################# Create tablecontent & comboboxes ###################
    
    def dosomething(index):
        widget = app.sender()
        print('widget object:', widget)
        print('widget myname:', widget.my_name)
        print('widget index:', combo_list.index(widget))
        print('option index:', index)
    
    #---------------------------------------------------------------------
    
    names = ['Name 1', 'Name 2', 'Name 3', 'Name 4']
    combo_option_list = ["Choose...", "Option 1", "Option 2", "Option 3", "Option 4"]
    
    combo_list = []
    
    for i, name in enumerate(names):
    
        tableWidget.setItem(i, 0, QtWidgets.QTableWidgetItem(name))
    
        combobox = QtWidgets.QComboBox()
        combobox.addItems(combo_option_list)
        combobox.my_name = name + ' (i=' + str(i) + ')'
        combobox.currentIndexChanged.connect(dosomething)
    
        combo_list.append(combobox)
    
        tableWidget.setCellWidget(i, 1, combobox)
    
    #---------------------------------------------------------------------
    
    sys.exit(app.exec_())
    

    Inside dosomething you can use app.sender() to get widget which was clicked - and then you can use it to do something with this widget.

    PyQt executes dosomething with argument - it is index of selected option in combobox.

    To get index of widget in combo_list you can use standard list method combo_list.index(widget)

    But you can also create own variable in combobox (ie. my_name) to keep index or other value

    combobox.my_name = some_value
    

    and later you can get in dosomething

    value = widget.my_name
    

    BTW:

    instead of addItem(one_option) and for loop you can use addItems(option_list)

    You can use enumerate(names) and you will not need i = 0 and i += 1

    for i, j in enumerate(names):
    

    You can create combo_option_list before for loop.