findChild returns None with custom widget - python

I have created a custom Qt widget in Python and managed to get it to load into the form at runtime however when I try and use findChild to grab it back of the form instance I get None back.
The widget is loaded and I can see it if I print out the names and objects on the form:
DEBUG:root:<PyQt4.QtGui.QCheckBox object at 0x11358030>
DEBUG:root:Near_Other_Infrastructure
DEBUG:root:<PyQt4.QtGui.QCheckBox object at 0x113582B8>
DEBUG:root:photo
DEBUG:root:<imagewidget.QMapImageWidget object at 0x113586A8>
This is the code:
images = self.forminstance.findChild(QMapImageWidget)
Update:
Seems doing this works:
images = self.forminstance.findChild(QWidget, "photo")
and it returns DEBUG:root:<imagewidget.QMapImageWidget object at 0x113586A8>
although I would really perfer to just get the control via the type without using the name.
Any ideas?

I also had this problem.
One easy solution is to find a non-custom base class and cast.
Custom* ptr = dynamic_cast<QWidget*>(root->findChild<QWidget*>("MyWidgetName"));
if (ptr)
{
//...whatever
}

Related

Selecting property to access programmatically

Given:
import configs
thingToLook = 'value'
channels = configs.value
Can I do something like
channels = config[thingToLook]
which is equivalent to
channels = config.value
?
If I do
channels = configs[thingToLook]
I get:
TypeError: 'module' object has no attribute '__getitem__'
I am trying to select the property to get from configs programmatically so I can set it via a string.
Unlike JavaScript, Python differentiates between items (bracket access) and attributes (dot access). Syntax that works for accessing one doesn't (usually) work for accessing the other.
You can use the getattr function to dynamically look up an attribute:
getattr(configs, thinkToLook)
and optionally set a default if nothing is found:
getattr(configs, thinkToLook, False)
config.value and config['value'] are not the same. They call different methods of the instance.
config.value is the same as config.__getattr__('value').
config['value'] is the same as config.__getitem__('value').
For more information look at this: https://docs.python.org/2/reference/datamodel.html

Problems getting object names

I have a blender scene with a few objects, I would get the object name when mouse is over one of them, setting a property of an empy object.
What I have now is just the list of the scene objects. What can I do?
import GameLogic
cont=GameLogic.getCurrentController()
obj=cont.getOwner()
print obj
objlist=GameLogic.getCurrentScene().getObjectList()
print objlist
sen=cont.getSensor('sensor')
if sen.isPositive():
print objlist[0]
PropName=.... #how to set this with the object name?
print PropName
I suppose you can use SCA_MouseSensor sensor and its hitObject property to get the last object the mouse was over. It returns None or an object of KX_GameObject type. When you get it, you can use its name property to get the name (or just access other properties of the object).
Reference links:
SCA_MouseSensor in API documentation
KX_GameObject in API documentation
I haven't tested this yet, but I suppose it should work when used in Blender Game Engine. The information I've found refers to Blender 2.59, so make sure use are using appropriate version of the application.
In order to be useful to someone else, I answer my own question. What I've done was to set a mouse over sensor to each objects within the scene and that add a python script controller, in order to set a property of the scene Empty object.
import GameLogic
import Rasterizer as r
r.showMouse(1) #just in order to get the mouse visible within the game engine
print 'SetProperty.py\n'
cont=GameLogic.getCurrentController()
obj=cont.getOwner()
emptyOb = GameLogic.getCurrentScene().getObjectList()["OBEmpty"]
emptyOb.EmptyProp=obj
print 'object name, within emptyProp: ', emptyOb.EmptyProp

Dynamically building up types in python

Suppose I am building a composite set of types:
def subordinate_type(params):
#Dink with stuff
a = type(myname, (), dict_of_fields)
return a()
def toplevel(params)
lots_of_types = dict(keys, values)
myawesomedynamictype = type(toplevelname, (), lots_of_types)
#Now I want to edit some of the values in myawesomedynamictype's
#lots_of_types.
return myawesomedynamictype()
In this particular case, I want a reference to the "typeclass" myawesomedynamictype inserted into lots_of_types.
I've tried to iterate through lots_of_types and set it, supposing that the references were pointed at the same thing, but I found that the myawesomedynamictype got corrupted and lost its fields.
The problem I'm trying to solve is that I get values related to the type subordinate_type, and I need to generate a toplevel instantiation based on subordinate_type.
This is an ancient question, and because it's not clear what the code is trying to do (being a code gist rather than working code), it's a little hard to answer.
But it sounds like you want a reference to the dynamically created class "myawesomedynamictype" on the class itself. A copy of (I believe a copy of) the dictionary lots_of_types became the __dict__ of this new class when you called type() to construct it.
So, just set a new attribute on the class to have a value of the class you just constructed; Is that what you were after?
def toplevel(params)
lots_of_types = dict(keys, values)
myawesomedynamictype = type(toplevelname, (), lots_of_types)
myawesomedynamictype.myawesomedynamictype = myawesomedynamictype
return myawesomedynamictype()

How can I tell if an Expando subclass has a property defined?

I'm creating an app that I want to have an expandable set of properties (each a RatingProperty) I also want to validate that any dynamic properties are of the RatingProperty type.
In the Expando documentation it says:
Tip: If you want to validate a dynamic property value using a Property class, you can instantiate the Property class and call its validate() method on the value.
So if I want to validate a dynamic property I need to know what the class's non-dynamic properties are. How can I ask my class what it's defined properties are?
I've considered creating a class method that takes a string and returns true if that string is in a list of property names that I create and maintain, but it seems like a hack. I've searched the Google for tips, but haven't had any luck.
Thanks,
Pat
After a bit more research (damn you lazyweb!) I've found a solution that I think is acceptable:
A dynamic property can't be of a db subclassed property type. Thus, there are two distinct steps that must be taken. First you need to create an instance of your property class and validate your value:
test = db.RatingProperty()
if test.validate(valueToSave):
#do your thing
Next you need to check if the property you want to save is a declared property:
if valueToSaveKey not in myObject.properties():
#if not save it as desired
myObject.valueToSaveKey = valueToSave
The down side here is that the value you save isn't stored as the property type you want.
http://code.google.com/appengine/docs/python/datastore/modelclass.html#Model_properties
db.Model has methods to find out all the properties on an instance.
The class exposes a list of Property objects: db.Model.properties()
The instance exposes the dynamic names only: instance.dynamic_properties()
You want to loop through the list and build Property objects, and run p.validate().
for p_name in instance.dynamic_properties():
p = db.RatingProperty()
p.validate() # raises BadValueError, etc.
I may be misunderstanding your question, but if you have a list of properties you expect to find, why not just use a standard db.Model, instead of an Expando? You can add additional properties to a Model class, as long as you either provide a default or don't make them required.
It's actually quite easy!
ExpandoObject implements (IDictionary<String, Object>) so you just need to do this :
dynamic person = new ExpandoObject();
person.FirstName = "Barack";
person.LastName = "Obama"
(((IDictionary<String, Object>)person).Keys
=> { "FirstName", "LastName" }
(((IDictionary<String, Object>)person).ContainsKey("FirstName")
=> true
Note: You need to explicitly cast to (IDictionary<string, object> because ExpandoObject explicitly implements this interface - and the instance itself doesn't have ContainsKey() or Keys.
Don't expect this method to work with all dynamic objects - just ExpandoObject and anything else that implements this interface.

How do I get the key value of a db.ReferenceProperty without a database hit?

Is there a way to get the key (or id) value of a db.ReferenceProperty, without dereferencing the actual entity it points to? I have been digging around - it looks like the key is stored as the property name preceeded with an _, but I have been unable to get any code working. Examples would be much appreciated. Thanks.
EDIT: Here is what I have unsuccessfully tried:
class Comment(db.Model):
series = db.ReferenceProperty(reference_class=Series);
def series_id(self):
return self._series
And in my template:
more
The result:
more
Actually, the way that you are advocating accessing the key for a ReferenceProperty might well not exist in the future. Attributes that begin with '_' in python are generally accepted to be "protected" in that things that are closely bound and intimate with its implementation can use them, but things that are updated with the implementation must change when it changes.
However, there is a way through the public interface that you can access the key for your reference-property so that it will be safe in the future. I'll revise the above example:
class Comment(db.Model):
series = db.ReferenceProperty(reference_class=Series);
def series_id(self):
return Comment.series.get_value_for_datastore(self)
When you access properties via the class it is associated, you get the property object itself, which has a public method that can get the underlying values.
You're correct - the key is stored as the property name prefixed with '_'. You should just be able to access it directly on the model object. Can you demonstrate what you're trying? I've used this technique in the past with no problems.
Edit: Have you tried calling series_id() directly, or referencing _series in your template directly? I'm not sure whether Django automatically calls methods with no arguments if you specify them in this context. You could also try putting the #property decorator on the method.

Categories