Check row by row in QTableWidget to affect QCombobox
<p>I have a QTableWidget, 2 Columns in which the first column contains the name of items while the second column is populated with qcomboboxes (created using cellwidgets) which contains a list of color options (eg. "", RED, BLUE, GREEN)</p>

<p>For example, in the following table, items denoted with * has a variable called <code>color_set</code>, I am trying to achieve as follows:</p>

<ul>
<li>it will lookup the names of items in the scene</li>
<li>then it will go through a function to check and see if the item
<code>shirt_01</code> contains a variable called <code>color_set</code></li>
<li>If the variable exists, say if it is RED, it will then lookup the list of options in the combobox and display RED as the value</li>
<li>If the variable does not exists, it will displays a blank field instead</li>
<li><p>this function/values populate the table with information before the ui is launched, it is not a button clicked function etc.</p>

<pre><code>Name of items   | Color Options
  shirt_01*     |     RED
  shirt_02      | 
  pants*        |    GREEN
</code></pre></li>
</ul>

<p>However, instead of getting my ui to output as above, I got the following result:</p>

<pre><code>    Name of items   | Color Options
      shirt_01*     |     RED
      shirt_02      |     RED
      pants*        |    GREEN
</code></pre>

<p>For some reasons, the <code>shirt_02</code> seems to got 'tangled' and displayed the same result as <code>shirt_01</code>. And I think it could possibly be due to how my logic was written but I could not figure it out or because I keep tying my output result to <code>self.color_combobox</code> as my code initially checks through the first column then find the matching text in the second column.
But I keep getting error at the line - item_name has no attribute .text()</p>

<pre><code>import maya.cmds as cmds
from PyQt4 import QtGui, QtCore
import json

def get_all_mesh():
    all_mesh = cmds.listRelatives(cmds.ls(type = 'mesh'), parent=True)
    return all_mesh

def read_json(node_name):
    # checks if the node_name exists in the json file
    with open('/Desktop/car_colors.json') as data_file:
        data = json.load(data_file)

        items = set()
        for index, name in enumerate(data):
            # if the name is in the json, it will states the color
            if node_name in name:
                for item in (data[name]):
                    #print "{0} - {1}".format(name, item)
                    items.add(item)
    return items

def attrToPy(objAttr):
    stringAttrData = str(cmds.getAttr(objAttr))
    loadedData = cPickle.loads(stringAttrData)

    return loadedData


class testTableView(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.setWindowTitle('Color Test')
        self.setModal(False)

        self.all_mesh = get_all_mesh()

        # Build the GUI
        self.init_ui()
        self.populate_data()


    def init_ui(self):
        # Table setup
        self.mesh_table = QtGui.QTableWidget()
        self.mesh_table.setRowCount(len(self.all_mesh))
        self.mesh_table.setColumnCount(3)
        self.mesh_table.setHorizontalHeaderLabels(['Mesh Found', 'Color for Mesh'])
        self.md_insert_color_btn = QtGui.QPushButton('Apply color')

        # Layout
        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.mesh_table)
        self.layout.addWidget(self.md_insert_color_btn)
        self.setLayout(self.layout)

    def populate_data(self):
        geo_name = self.all_mesh

        for row_index, geo_item in enumerate(geo_name):
            new_item = QtGui.QTableWidgetItem(geo_item)
            # Add in each and every mesh found in scene and append them into rows
            self.mesh_table.setItem(row_index, 0, new_item)

            geo_exclude_num = ''.join(i for i in geo_item if not i.isdigit())
            color_list = read_json(geo_exclude_num)

            color_list.add("")
            # Insert in the color
            self.color_combobox = QtGui.QComboBox()
            #color_list = get_color()
            self.color_combobox.addItems(list(sorted(color_list)))
            self.mesh_table.setCellWidget(row_index, 1, self.color_combobox)
            self.color_value_to_combobox()

    def color_value_to_combobox(self):
        obj_nodes = get_all_mesh()
        for node in obj_nodes:
            # This attribute is stored in the Extra Attributes
            objAttr = '%s.pyPickle'%node
            storedData = attrToPy(objAttr)

            if 'color_set' in storedData:
                color_variant = storedData['color_set']
                combo_index = self.color_combobox.findText(color_variant, QtCore.Qt.MatchFixedString)
                self.color_combobox.setCurrentIndex(0 if combo_index &lt; 0 else combo_index)


# To opent the dialog window
dialog = testTableView()
dialog.show()
</code></pre>

<p>Is there anyway in which I can make my ui to check for the list of item in scene, tallies which name and combobox it should go (in terms of which rows/columns)? Otherwise what other ways can i approach?</p>

<p>EDIT: This is the attachment that I did it quick - <a href="https://www.mediafire.com/?fy67i4105j6z1tp" rel="nofollow">Link</a>
If you run the UI, you will notice that pCube1 has the color "red" while pCube2 is "blue", however both the comboboxes will turn up as blue instead</p>

<p>Ok, so the problem was in <code>color_value_to_combobox</code>. Instead of setting the combobox for ALL objects, you need to specify what object and combobox the function needs to work on. The major flaw was that you were using <code>self.color_combobox</code> to set with every time, so every object would keep setting the same combobox! It needs to be more generic. Instead of storing the combobox to <code>self.color_combobox</code> I would normally store it in a list, otherwise you can't access all of them anymore, but I leave that to you.</p>

<p>Anyways, I just had to change the end of <code>populate_data</code> and <code>color_value_to_combobox</code>. Now <code>cube1</code> shows <code>red</code>, and <code>cube2</code> shows <code>blue</code>.</p>

<pre><code>import maya.cmds as cmds
from PyQt4 import QtGui, QtCore
import json
import cPickle

def get_all_mesh():
    all_mesh = cmds.listRelatives(cmds.ls(type = 'mesh'), parent=True)
    return all_mesh

def read_json(node_name):
    # checks if the node_name exists in the json file
    with open('/Desktop/car_colors.json') as data_file:
        data = json.load(data_file)

        items = set()
        for index, name in enumerate(data):
            # if the name is in the json, it will states the color
            if node_name in name:
                for item in (data[name]):
                    #print "{0} - {1}".format(name, item)
                    items.add(item)
    return items

def attrToPy(objAttr):
    stringAttrData = str(cmds.getAttr(objAttr))
    loadedData = cPickle.loads(stringAttrData)

    return loadedData


class testTableView(QtGui.QDialog):
    def __init__(self, parent=None):
        QtGui.QDialog.__init__(self, parent)
        self.setWindowTitle('Color Test')
        #self.setModal(False)

        self.all_mesh = get_all_mesh()

        # Build the GUI
        self.init_ui()
        self.populate_data()


    def init_ui(self):
        # Table setup
        self.mesh_table = QtGui.QTableWidget()
        self.mesh_table.setRowCount(len(self.all_mesh))
        self.mesh_table.setColumnCount(3)
        self.mesh_table.setHorizontalHeaderLabels(['Mesh Found', 'Color for Mesh'])
        self.md_insert_color_btn = QtGui.QPushButton('Apply color')

        # Layout
        self.layout = QtGui.QVBoxLayout()
        self.layout.addWidget(self.mesh_table)
        self.layout.addWidget(self.md_insert_color_btn)
        self.setLayout(self.layout)

    def populate_data(self):
        geo_name = self.all_mesh

        for row_index, geo_item in enumerate(geo_name):
            new_item = QtGui.QTableWidgetItem(geo_item)
            # Add in each and every mesh found in scene and append them into rows
            self.mesh_table.setItem(row_index, 0, new_item)

            geo_exclude_num = ''.join(i for i in geo_item if not i.isdigit())
            color_list = read_json(geo_exclude_num)

            color_list.add("")
            # Insert in the color
            color_combobox = QtGui.QComboBox()
            #color_list = get_color()
            color_combobox.addItems(list(sorted(color_list)))
            self.mesh_table.setCellWidget(row_index, 1, color_combobox)

            self.color_value_to_combobox(geo_item, color_combobox) # Pass the object and combobox you want to set

    # This use to work on all mesh objects, but only edits a single combobox. This is wrong!
    def color_value_to_combobox(self, node, combobox):
        # This attribute is stored in the Extra Attributes
        objAttr = '%s.pyPickle'%node
        storedData = attrToPy(objAttr)

        if 'color_set' in storedData:
            color_variant = storedData['color_set']
            combo_index = combobox.findText(color_variant, QtCore.Qt.MatchFixedString)
            combobox.setCurrentIndex(0 if combo_index &lt; 0 else combo_index) # Needs to work on the proper combobox!


# To opent the dialog window
dialog = testTableView()
dialog.show()
</code></pre>

python pyqt maya qtablewidget qcombobox