Getting color change to be in effect realtime

50 views
Skip to first unread message

yann19

unread,
Oct 3, 2016, 3:32:03 PM10/3/16
to Python Programming for Autodesk Maya
Hi all, I was wondering if someone could kindly direct me on this and perhaps how I should do it?

Say if I have a model (with lots of polygon), and I am trying to grab some specified pieces of geometry that has '_defaultPaint_' embedded in their naming...

While I can use cmds.ls('*_defaultPaint_*') to filter them out, at the same time, I would also like to grab its shaders (each piece of geo has its own shader) in which I will have this UI that shows a list of colors, and as I change the options within a combobox perhaps, eg. from their default red color, and I selected 'yellow', it will reflect the changes in their shaders but as well as in the viewport real-time.

How should I approach in doing so?

Currently for my UI, I have a QTableWidget of 2 columns, first column that denotes the models in the scene, and the second column populated by a QComboBox is filled with the color options stemming from a json file that specifically states the different colors given to the model.
So far, I have succedded in populating thses 2 columns, however getting the changes to be in effect in real-time is lacking for me. 
I can try using a QPushButton and hardcode it, along with the attributes of the color etc but that is not effective and not really real-time since it can only happens upon a click on the push button.

Any insights?

This is a portion of the code that I have did..


def get_all_mesh():
    all_mesh
= cmds.listRelatives(cmds.ls(type = 'mesh'), parent=True)
   
# Result: [u'pCube1', u'pSphere1', u'pPlane1'] #
   
return all_mesh


def get_color(node_name):
   
# checks if the node_name exists in the json file
   
with open('/Desktop/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




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
= get_color(geo_exclude_num)


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


# To opent the dialog window
dialog
= testTableView()
dialog
.show()


I have read somewhere that using mvc (model/ view/ controller) may help? but how do i start off?

Justin Israel

unread,
Oct 3, 2016, 4:57:44 PM10/3/16
to python_in...@googlegroups.com
Firstly, can you be a little more specific about what you want to see when you say "real time"? Do you mean you want the effects of changing colors in the combo box to immediately apply, whereas right now you have to click a button? Or are you saying you want feedback from Maya to update your GUI?

If you are looking to have your combo box apply the change immediately, you could look at wiring up the signal for when a combo box changes:

Justin

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/eeb630dc-5e5e-4b0c-b2da-4129effac47f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

yann19

unread,
Oct 3, 2016, 8:36:47 PM10/3/16
to Python Programming for Autodesk Maya
Sorry Justin, that I am not phrasing myself correctly.
By 'real-time', I mean to say, the colors will be applied with immediate effect as soon the options in the combobox is changed.
For example, if I select 'red' in the combobox for pCube1, the pCube1 in scene will be colored red.

And The thing about clicking with button - I mean to say that I am able to do that but it is not something that I wanted. I apologize if this has caused confusion...
By the way, I did tried replacing all the combobox to self.combobox and creating a new function as follows:
def __init__(self, parent=None):
    ...
    self.init_ui()
    self.populate_data()
    self.connect_signals()
def connect_signals(self):
   
self.combobox.currentIndexChanged.connect(self.append_color)

def append_color(self):
   
for row in xrange(self.mesh_table.rowCount()):
        color_sel
= self.mesh_table.cellWidget(row, 1).currentText()
       
print color_sel


However it does not seems to be working..

Side-tracking a bit though, if I am to convert the current code I have done into this 'mode/view/controller' I have done, will it be difficult to do so?
I asked this because when I tried doing the following:
from PyQt4 import QtGui, QtCore
import sys

def get_geos():

    all_mesh
= cmds.listRelatives(cmds.ls(type = 'mesh'), parent=True)

   
return all_mesh


class test(QtGui.QWidget):
   
# Our main window will be a QListView
    list
= QtGui.QTableView()
    list
.setWindowTitle('Example List')
    list
.setMinimumSize(600, 400)
     
   
# Create an empty model for the list's data
    model
= QtGui.QStandardItemModel(list)
    all_geos
= get_geos()
   
     
   
for geo in all_geos:
       
# create an item with a caption
        item
= QtGui.QStandardItem(geo)
     
       
# Add the item to the model
        model
.appendRow(item)
     
   
# Apply the model to the list view
    list
.setModel(model)
     
   
# Show the window and run the app
    list
.show()

As I try editing the name of the nodes that I set in the QTableView, the changes are not being reflected and I did quite some trial and errors before I came upon 'QStandardItem' so that the nodes' name will be inputted, as there aren't many tutorials online for me to reference.

yann19

unread,
Oct 3, 2016, 8:52:09 PM10/3/16
to Python Programming for Autodesk Maya
Okay, currentIndexChanged works, I have placed it wrongly instead of it being under the connect_signals functions, I should have placed it under the populate_data function..

Justin Israel

unread,
Oct 3, 2016, 9:01:35 PM10/3/16
to python_in...@googlegroups.com
On Tue, Oct 4, 2016 at 1:52 PM yann19 <yang...@gmail.com> wrote:
Okay, currentIndexChanged works, I have placed it wrongly instead of it being under the connect_signals functions, I should have placed it under the populate_data function..

I was going to say something about that, until I just saw this reply. Originally you were creating individual combobox instances, and each one should have its signal hooked up to handle the color change for the associate model. And then in your later example you tried to store a single combobox reference as "self.combobox" which I know would have caused you problems. So if you are back to connecting each discreet combo, then it should work.

As for the mode/view/controller thing, I am not sure what that would gain you in terms of this whole color problem. Either way, you have to update the names and colors in some place, whether it be in a model, or in the integrated high-level widget. 

 And for the problem of your model/view not working as you would expect, I am not sure what is wrong from the code example you gave. You seem to be setting the model on the view, and adding model items. What approach are you using to edit the names? If you edit them interactively in your view, then you should be seeing them in your model items. And if you are setting them via modelItem.setText(), then you should be seeing them change in the view.

Justin

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages