Simple PyQt question about QCheckBox

I am tryin to set up some checkboxes that when enabled and disabled, will update the values of extra attributes on nodes in my scene.

I’m using the partial method from functools to pass data from the checkbox to my function so i know which attribute to modify and what the new value of the check box is.

however, i’m running into a problem where i can’t seem to retrieve the new value of the checkbox, i always get a value of FALSE.

attrCb = QtGui.QCheckBox(newAttrName)
self.connect(attrCb, QtCore.SIGNAL(‘stateChanged(int)’), partial(myFunctionUpdateNode, newAttrName, attrCb.isChecked()))

how can i run a function when the CheckBox is changed and also retrieve the new value at the same time?

Thanks.

I ran into that same issue last night except with a QlistWidget but it kept returning the first index of the list even though I had it looking for currentItem(). I can’t remember off the top of my head now, but I will post what I did when I get home if no one else can help in the mean time, it was something dumb if I remember.

The first argument received by your slot should be the new Qt.CheckState.
You don’t need to pass an extra isChecked.


def mySlot (checkState, newAttrName):
    pass

That worked except I ran into trouble getting the arguments to pass correctly.

In order to get the new value of the checkbox to pass into my function, i had to use keywords so the other arguments were passed in correctly.

Thanks for the help!

Another question about CheckBoxes…

is there a way i can control the look of TriState checkboxes?
looks like maya uses the same graphic when checkboxes are in both the partial and on states…
Can i make the partial state look grayed-out?

A few things:
1- is that code above running inside of a loop?
2- IMO you should never use the ‘self.connect’ signal connection with pyqt. It is shit. Here’s a much easier way to write what you want:
attrCb.stateChanged.connect(partial(myFunctionUpdateNode, newAttrName, attrCb.isChecked()))
3- This is more personal but I generally avoid the stuff from functools like partial. You can just write it yourself with lambdas and nested functions. But if it floats your boat, go for it. Ie, I’d rather ‘attribCb.stateChanged.connect(lambda state: myFunctionUpdateNode(state, newAttrName))’

[QUOTE=rgkovach123;15561]Another question about CheckBoxes…

is there a way i can control the look of TriState checkboxes?
looks like maya uses the same graphic when checkboxes are in both the partial and on states…
Can i make the partial state look grayed-out?[/QUOTE]

I’ve run into this same thing.

When launching through QtGui.QApplicaiton it works amazingly. The QtCore.Qt.PartiallyChecked flag works, but inside of maya it just looks like there are only two options on/off.

The reason behind needing to see partially checked is creating light-linking-tool that works for our pipeline, and much like light-linking-highlighting I need to have a ‘third’ display that something ‘below’ but not everything in the hierarchy is selected.
Has there been a solution to this I haven’t found, or any other creative solutions?

I’ve come back to this tool and i was trying out some of the advice offered.

To answer rob’s question, yes i am looping through a dictionary and creating controls based on the keys.

            self.connect(attrCB, 
                         QtCore.SIGNAL('toggled(bool)'), 
                         partial(self.updateAttr, attrName=k, attrType='bool'))

I used the “toggled” signal rather than “stateChanged” because toggled returns 0 or 1, whereas stateChanged will return 0, 1, or 2.

anyway, I tried this:

 attrCB.toggled.connect(lambda state: self.updateAttr(state, attrName=k, attrType='bool'))

and it didn’t quite work… instead of each checkbox controlling a specific attribute, all the checkboxes control the first attribute modified.

to provide a little bit background, this is what i am trying to achieve.

a simple UI with a list of checkboxes. these checkboxes represent flags that have meaning outside of maya. the user selects some things in maya and set the checkboxes. the UI then has to loop through the objects, check if the attr exists, create it, and update it with the value from the checkbox.

since a new flag can be added at any time, I has a simple dictionary where the key is the attr name, and the value is the type.

I loop through the dictionary and create the controls when the ui is opened.

[QUOTE=rgkovach123;18478]
anyway, I tried this:

 attrCB.toggled.connect(lambda state: self.updateAttr(state, attrName=k, attrType='bool'))

and it didn’t quite work… instead of each checkbox controlling a specific attribute, all the checkboxes control the first attribute modified.[/QUOTE]

That’s a function of the behavior of lambdas. Any variables you put into the statement of a lambda won’t be evaluated until run time, at which point the loop has finished and k is at it’s final value, which is used by all the lambdas.

If you pass an argument as a default argument, it gets evaluated at definition-time, so:

attrCB.toggled.connect(lambda state, attrName=k: self.updateAttr(state, attrName=attrName, attrType='bool'))

Should give you the expected behavior.

thanks for the explanation, that makes perfect sense!

I discovered that if you use setCheckState on a checkbox in stead of setChecked, it will make it a tristate checkbox.

Don’t do this…