I am using Kivy to build a simple app that would load different images in different tabs of a tabbed panel. The different Panel items should all behave similarly, but with different images, so I created a widget class. I am trying to initialize my app using the kv language like in many examples.
Currently, I am unable to make it work, because I cannot find how to pass the file names in a list from the kv language part to the widget instance. I am able to work with other Properties, but the ListProperty has me stumped.
Here is a snippet from my code:
Builder.load_string("""
<MyMainClass>:
#stuff
TabbedPanelItem:
MyClassLayout:
filenames: ['pic1.jpg', 'pic2.jpg', 'pic3.jpg', 'pic4.jpg']
#other TabbedPanelItems like the one above,
#with different strings in the list
""")
def MyMainClass(TabbedPanel):
pass
def MyClassLayout(FloatLayout):
filenames = ListProperty([])
#rest of my class
Things I already tried:
Use different parentheses in assigning the list in the kv language part: I tried () and {}, as well as with no parentheses.
Initialize the ListProperty differently: I tried putting some string in it already.
Send different lists: I tried sending numbers instead of strings.
The result is always that the filenames list in my widget is always at the default value. That would be [] in the snippet above, or whatever I set in its declaration in my class.
Would someone please point out what it is I am doing wrong?
Thanks.
I managed to fix this.
The issue was that I was trying to read the lists in the constructor. However, they receive their value from the kv lang part after the widget object has finished its constructor.
As a fix, I call the method that reads the list like so:
Clock.schedule_once(self.late_init, 0.02)
I hope people find this and it helps them.
Related
I have created custom Django model-field subclasses based on CharField but which use to_python() to ensure that the model objects returned have more complex objects (some are lists, some are dicts with a specific format, etc.) -- I'm using MySQL so some of the PostGreSql field types are not available.
All is working great, but Pylint believes that all values in these fields will be strings and thus I get a lot of "unsupported-membership-test" and "unsubscriptable-object" warnings on code that uses these models. I can disable these individually, but I would prefer to let Pylint know that these models return certain object types. Type hints are not helping, e.g.:
class MealPrefs(models.Model):
user = ...foreign key...
prefs: dict[str, list[str]] = \
custom_fields.DictOfListsExtendsCharField(
default={'breakfast': ['cereal', 'toast'],
'lunch': ['sandwich']},
)
I know that certain built-in Django fields return correct types for Pylint (CharField, IntegerField) and certain other extensions have figured out ways of specifying their type so Pylint is happy (MultiSelectField) but digging into their code, I can't figure out where the "magic" specifying the type returned would be.
(note: this question is not related to the INPUT:type of Django form fields)
Thanks!
I had a look at this out of curiosity, and I think most of the "magic" actually comes for pytest-django.
In the Django source code, e.g. for CharField, there is nothing that could really give a type hinter the notion that this is a string. And since the class inherits only from Field, which is also the parent of other non-string fields, the knowledge needs to be encoded elsewhere.
On the other hand, digging through the source code for pylint-django, though, I found where this most likely happens:
in pylint_django.transforms.fields, several fields are hardcoded in a similar fashion:
_STR_FIELDS = ('CharField', 'SlugField', 'URLField', 'TextField', 'EmailField',
'CommaSeparatedIntegerField', 'FilePathField', 'GenericIPAddressField',
'IPAddressField', 'RegexField', 'SlugField')
Further below, a suspiciously named function apply_type_shim, adds information to the class based on the type of field it is (either 'str', 'int', 'dict', 'list', etc.)
This additional information is passed to inference_tip, which according to the astroid docs, is used to add inference info (emphasis mine):
astroid can be used as more than an AST library, it also offers some
basic support of inference, it can infer what names might mean in a
given context, it can be used to solve attributes in a highly complex
class hierarchy, etc. We call this mechanism generally inference
throughout the project.
astroid is the underlying library used by Pylint to represent Python code, so I'm pretty sure that's how the information gets passed to Pylint. If you follow what happens when you import the plugin, you'll find this interesting bit in pylint_django/.plugin, where it actually imports the transforms, effectively adding the inference tip to the AST node.
I think if you want to achieve the same with your own classes, you could either:
Directly derive from another Django model class that already has the associated type you're looking for.
Create, and register an equivalent pylint plugin, that would also use Astroid to add information to the class so that Pylint know what to do with it.
I thought initially that you use a plugin pylint-django, but maybe you explicitly use prospector that automatically installs pylint-django if it finds Django.
The checker pylint neither its plugin doesn't check the code by use information from Python type annotations (PEP 484). It can parse a code with annotations without understanding them and e.g. not to warn about "unused-import" if a name is used in annotations only. The message unsupported-membership-test is reported in a line with expression something in object_A simply if the class A() doesn't have a method __contains__. Similarly the message unsubscriptable-object is related to method __getitem__.
You can patch pylint-django for your custom fields this way:
Add a function:
def my_apply_type_shim(cls, _context=None): # noqa
if cls.name == 'MyListField':
base_nodes = scoped_nodes.builtin_lookup('list')
elif cls.name == 'MyDictField':
base_nodes = scoped_nodes.builtin_lookup('dict')
else:
return apply_type_shim(cls, _context)
base_nodes = [n for n in base_nodes[1] if not isinstance(n, nodes.ImportFrom)]
return iter([cls] + base_nodes)
into pylint_django/transforms/fields.py
and also replace apply_type_shim by my_apply_type_shim in the same file at this line:
def add_transforms(manager):
manager.register_transform(nodes.ClassDef, inference_tip(my_apply_type_shim), is_model_or_form_field)
This adds base classes list or dict respectively, with their magic methods explained above, to your custom field classes if they are used in a Model or FormView.
Notes:
I thought also about a plugin stub solution that does the same, but the alternative with "prospector" seems so complicated for SO that I prefer to simply patch the source after installation.
Classes Model or FormView are the only classes created by metaclasses, used in Django. It is a great idea to emulate a metaclass by a plugin code and to control the analysis simple attributes. If I remember, MyPy, referenced in some comment here, has also a plugin mypy-django for Django, but only for FormView, because writing annotations for django.db is more complicated than to work with attributes. - I was trying to work on it for one week.
I'm trying to export a CSV file in ServiceNow using the URL. I've applied my various filters and I've personalized the list columns I need. The problem is, when I use the URL to obtain the records, I get ALL the columns and not my personalized list columns. Can anyone tell me why this is happening?
The URL I'm using is as follows (sample, not the real URL):
https://abc.service-now.com/incident_list.do?sysparm_query=xyz
Can someone guide me as to whats missing in the URL?
There's a URL parameter sysparm_view that you can add to specify the name of the view you want to use, but it sounds like you may still be missing something.
There's a difference between "Personalizing" a list layout and "Configuring" a list layout:
The former ("personalizing") is a layout that is visible only to you.
There's no way to give a URL to someone that will give them that
particular list layout.
The latter ("configuring") is what you'll
need to use to define list layout configuration that is accessible to
any user, and which can be targeted via the sysparm_view URL
parameter
This wiki article defines views:
http://wiki.servicenow.com/?title=View_Management#Creating_Views
If you follow the steps in "Creating Views", you'll end up with a view name (as specified by you when you created it, say you called it kage77. Then you'd be able to send someone a URL with sysparm_view=kage77 and they'd see the list layout you associated with that view:
https://abc.service-now.com/incident_list.do?sysparm_query=xyz&sysparm_view=kage77
You have to include the file type as well like CSV/ XLSX/PDF
https://instance.service-now.com/incident_list.do?CSV
you can add few parameters,
&sysparm_query=active=true
&sysparm_fields=number%2Cshort_description
&sysparm_orderby=sys_id
More reference: https://docs.servicenow.com/bundle/london-platform-administration/page/administer/exporting-data/task/t_ExportDirectlyFromTheURL.html
I have just started using Qt creator. I have created a simple form in QT4 designer and I used python for it. It is a simple form with two fields and a button. These two fields populate values from the device that I have defined in my jive.I am using the following statement in python to read the values from the device:
taurus.Attribute('device_name/instance_name/attribute_name').getDisplayValue()
This statement fetches the value of the attribute and I am appending this value to the text fields I have on the form.I have an "import taurus" statement in my python code.I am trying to do the similar thing in C++ but I am not sure on how we can read the values from the device defined in jive. So could you let me know how this can be achieved.
This question is really framework-specific. There isn't many Tango users on StackOverflow. Have a look at the QTango documentation on QTWatcher and QTWriter.
Here is a basic example where the attribute value from your device is linked to a ProgressBar:
QProgressBar *pbar = new QProgressBar(this);
QTWatcher *pbarWatcher = new QTWatcher(this);
pbarWatcher->attach(pbar, SLOT(setValue(int)));
// configure maximum and minimum values when available
pbarWatcher->setAutoConfSlot(QTWatcher::Min, SLOT(setMinimum(int)));
pbarWatcher->setAutoConfSlot(QTWatcher::Max, SLOT(setMaximum(int)));
pbarWatcher->setSource("$1/short_scalar_ro");
which combinations of Widget/Template and ClientBundleare allowed, and are there any known limitation / things you should consider when using them.
Afaik something like:
#Template(""{0}\"<p>not allowed</p>")
SafeHtml iconONLY(Widget w);
isn't allowed since it throws an error.
Something like
#Template("{0}<p>not allowed</p>")
SafeHtml iconONLY(Element e);
and use it with something like iconONLY(w.getElement()); is possible, but the Widget loses all functionality, because it's attache method isn't executed correctly.
To summ it up, I assume that Templates are not intended to have Widgets placed inside them!
ClientBundle are intended hold the content Widgets. Using them inside other elements e.g: like
#Template("{0}<p>not allowed</p>")
SafeHtml iconONLY(SafeUrl safeurl);
called with iconONLYimageResource.getSafeUrl); can cause problems...
Are my assumptions correct? Please tell me if you tryed/ used one of the combination and how it worked?
The first and the second ones makes sense that they don't work, since you are trying to insert just the element or widget into a string (SafeHtml is at the end of the day just a String) - of course the event wiring won't work. Widgets cant be cloned like that, there is more to them then just the element they are made of.
The last is an error because you are putting a Uri into the text content - you probably mean something like
#Template("<img src=\"{0}\" /><p>not allowed</p>")
SafeHtml iconONLY(SafeUri safeurl);
to display an image.
What are you trying to do? If trying to display an image, putting the SafeUri in an img tag is one option, another would be to put together a SafeHtml instance to insert:
#Template("{0}<p>not allowed<p>")
SafeHtml iconONLY(SafeHtml icon);
//...
AbstractImagePrototype proto = AbstractImagePrototype.create(icon);
SafeHtml iconHtml = SafeHtmlUtils.fromTrustedString(proto.getHTML());
template.iconONLY(iconHtml);
The basic idea of SafeHtml is that you build up strings of html instead of dom elements - this allows those strings to be reused, or to all be injected at once (which is usually faster than appending elements to the dom) - this is not how widgets are added to one another, and trying to manipulate widgets like this will just end up with missing pieces, as you've noticed.
I'm trying to display a directory tree from a a treebeard model. The annotated list method suggested in the treebeard tutorial works fine, but I'd like to include id information in the data tree.
The dump_bulk() has all the info I need, but as a python and django newbie I'm strugglling to find a way to extract the information and display it in the template.
I've thought about switching to javascript, and parsing the json string, but javascript doesn't like the u prefix before the string values. Is there a simple way to avoid the u prefix?
I've also thought about writing a function based on the get_annotated_list() that does include id information. I'm assuming it should be possible to overload the get_annotated_ list so that id information is included, but I'm not too sure how to tackle that either.
Any and all suggestions to help me progress along the learning curve will be appreciated.
As you probably know, get_annotated_list() will return an array of tuples, in the form (node, info). info is just a dictionary, so you can iterate over the list, and add any additional key-pairs you like. E.g.,
for node, info in my_annotated_list:
info['foo'] = node.id
Pass this to your template, and you should be fine.
You can also use a generator. This is from a project I'm working on right now:
def annotated_menu_items(initial_header, menu_items):
headings = [initial_header]
for item, info in menu_items:
yield item, info, item.is_leaf(), headings[-1:][0]
if info['open']:
headings.append(item.title)
for close in info['close']:
headings.pop()
Here, I'm adding as extra info whether the node in question is a leaf, and pushing the title from the most recently opened node onto a stack so I can access it from deeper levels of the tree.
You say you're new to Python, so you may want to read up on generators. They you materialize the elements of a (potentially infinite) list lazily. In order to use it, you invoke the function which constructs the generator, then you can treat the generator object as an iterable. E.g.,
my_fancy_menus = annotated_menu_items("My Menu", my_annotated_list)
for menu in my_fancy_menus:
do_stuff(menu)
You can also pass generators to Django templates, where they are treated like lists.