Custom view with InstanceEditor - python

I'm working on a dynamic Traits UI where I can select the class to use for certain instances. I've got it working nicely using an InstanceEditor with a "values" argument containing InstanceFactoryChoice instances.
My problem appears when I want to specify a view to use for the selected instance. Using the "view" argument works if I omit the "values" argument, but with it I get the default view instead. The relevant part of the view looks like this:
Item('item',
show_label=False,
editor=InstanceEditor(
view=item_view,
values=[InstanceFactoryChoice(klass=k) for k in classes],
editable=True),
style='custom')
What's more confusing to me is that it also works as expected (i.e. uses the "item_view" view to display the instance) when I use the "simple" style instead of "custom". However, then the view appears in a new window, I want it to be inline.
Am I missing something here? I'm on TraitsUI 4.3.

OK, after some source-diving I found that adding the "view" argument to the InstanceFactoryChoice call instead seems to do what I want. Still, it seems there's an inconsistency in there somewhere...
InstanceFactoryChoice(klass=k, view=item_view)

Related

pyqt / is there any way to change options for all keySequenceEdit boxes? [duplicate]

I am developing a desktop application using pyside(qt), I want to access(iterate) all line edit components of QWidget. In qt I found two methods findChild and findChildren but there is no proper example found and My code shows error, 'form' object has no attribute 'findChild'.
Here 'form' is Qwidget form consist components lineEdit, comboboxes, Qpushbuttons etc.
Code:
lineEdits = form.findChild<QLineEdit>() //This is not working
lineEdits = form.findChild('QLineEdit) //This also not working
The signatures of findChild and findChildren are different in PySide/PyQt4 because there is no real equivalent to the C++ cast syntax in Python.
Instead, you have to pass a type (or tuple of types) as the first argument, and an optional string as the second argument (for matching the objectName).
So your example should look something like this:
lineEdits = form.findChildren(QtGui.QLineEdit)
Note that findChild and findChildren are methods of QObject - so if your form does not have them, it cannot be a QWidget (because all widgets inherit QObject).
Use this method QObject::findChildren(onst QString & name = QString()) with no parameters.
Omitting the name argument causes all object names to be matched.
Here is C++ example code:
QList<QLineEdit*> line_edits = form.findChildren<QLineEdit*>();

Python: How do I find / inspect what kind of arguments a function accepts?

I am trying to find out what what kind of arguments a function accepts. This is because I usually am unsure of what arguments a function even accepts in a first place. For example, consider a function from the the package Plotly:
fig.update_xaxes(ticks="outside")
I want to be able to know what are the different arguments ticks could be, i.e. ticks="inside" or ticks=outside.
Ideally the output would be that ticks accepts arguments such as: inside, outside, etc...
I usually get the parts pointed out by the arrows wrong because I don't know what ticks and tickson even accepts in the first place, as well as, what they do.
Right now I am using inspect. But, this doesn't tell me that I can input as arguments.
>>import inspect
>>inspect.getfullargspec(go.Figure.update_xaxes)
>>print(inspect.getsource(go.Figure.update_xaxes))
OUTPUT:
def update_xaxes(self, patch=None, selector=None, row=None, col=None, **kwargs):
"""
Perform a property update operation on all xaxis objects
that satisfy the specified selection criteria
Parameters
----------
patch: dict
Dictionary of property updates to be applied to all
xaxis objects that satisfy the selection criteria.
selector: dict or None (default None)
Dict to use as selection criteria.
xaxis objects will be selected if they contain
properties corresponding to all of the dictionary's keys, with
values that exactly match the supplied values. If None
(the default), all xaxis objects are selected.
row, col: int or None (default None)
Subplot row and column index of xaxis objects to select.
To select xaxis objects by row and column, the Figure
must have been created using plotly.subplots.make_subplots.
If None (the default), all xaxis objects are selected.
**kwargs
Additional property updates to apply to each selected
xaxis object. If a property is specified in
both patch and in **kwargs then the one in **kwargs
takes precedence.
Returns
-------
self
Returns the Figure object that the method was called on
"""
for obj in self.select_xaxes(selector=selector, row=row, col=col):
obj.update(patch, **kwargs)
return self
Using online documentation is always recommended but please keep in mind that documentation is not always generated directly from code or even if auto-generated it can contain errors or be out of date.
If you are using Jupyter Notebook you can get help on any object by running:
help(object)
If you are using an IDE like Eclipse the object options (parameters, etc..) are usually displayed to you as you type in your IDE:
And then when you are using a Figure instance:
Then when you click on it or choose ENTER when highlighting an item the parameters are inserted into your code like this:
In most IDE's you can also push CMD (Mac) or CTRL (Windows) when hovering over the library, function, object or a variable in your code (text changes into a link and the cursor changes to hand) and then click on it to go to its definition.
If the object or function is defined in another file, that file will automatically open in your IDE and the cursor will point to that object/function that you clicked.
In case of:
import plotly.graph_objects as go
fig = go.Figure(data, layout)
clicking on Figure will open _figure.py file and display this code:
I hope this helps.
In the specific case of plotly.graph_objects.Figure.update_xaxes(), you can pass in as a keyword argument anything that is accepted by the constructor of plotly.graph_objects.layout.Xaxis, and we will update the docstring and documentation to make that clearer. Note that plotly.graph_objects.layout.Xaxis accepts in its constructor what we call "magic underscores" meaning that for nested properties like title you can pass in title_font and so on, which are also not explicitly listed in that docstring. This is one of the downsides to having such a dynamic API.

Django reverse routes - two optional parameters

I have a question about Django and it's routing system. I believe that it can be powerfull, but right now I am struggling with one issue I don't experience when working in other frameworks and I can't seem to get a grip on it. Worth to mention that I don't have much experience with Django at this point.
The issue is simple - I have a view which takes two optional parameters, defined like this
def test_view(id=None, grid=None):
Both parameters are optional and frequently are not passed. Id can only be an integer and grid will never be an integer (it is a special string to control datagrid when I don't want to use sessions). I have a route defined like this:
url(a(r'^test_view (\/(?P<id>\d+))? (\/(?P<grid>[^\/]+))? \/?$'), views.test_view, name='test_view'),
This works great and I am not having trouble with using one-way routes. But when I try to use the reverse function or url template tag, following error occurs:
Reverse for 'test_view' with arguments '('20~id~desc~1',)' and keyword arguments '{}' not found.
In this example I tried to find reverse without the id, just with the grid parameter. I have tried various methods of passing parameters to the reverse function:
(grid, )
(None, grid)
('', grid)
{id=None, grid=grid}
All of them result in same error or similliar one.
Is there a way to implement this in django? Maybe just disable the cool URL for the grid parameter. That is how I do it in for example Nette framework for PHP, isntead of having an url like this: 'localhost/test_view/1/20~id~desc~1' I have url like this: 'localhost/test_view/1?grid=20~id~desc~1'. This would be completely sufficient, but I have no idea how to achive this in Django.
As you note in your question, the best way to achieve this is to use standard GET query parameters, rather than doing it in the path itself. In Django you do that exclusively in the view; the URL itself is then just
url(r'^test_view$', views.test_view, name='test_view'),
and you request it via localhost/test_view?id=1&grid=20~id~desc~1. You get the params from request.GET, which is a dictionary-like object; you can use .get so that it does not raise a KeyError when the key is not provided.
def test_view(request):
id = request.GET.get('id')
grid = request.GET.get('grid')

A sorted and filtered treemodel in Python Gtk+3..?

I am trying to get a treemodel (a liststore in fact) that can be filtered and also sorted. I have the following piece of code
self.modelfilter = self.liststore.filter_new()
self.modelfilter.set_visible_func(\
self._visible_filter_function)
self.treeview.set_model(self.modelfilter)
where self.liststore and self.treeview are standard Gtk.ListStore and Gtk.TreeView objects that I get from a glade file, and self._visible_filter_function is a filtering function.
The problem is that self.modelfilter does not seem to be sortable. When I click on the column headers (of the columns in self.treeview) to sort them, I get
Gtk-CRITICAL **: gtk_tree_sortable_get_sort_column_id: assertion `GTK_IS_TREE_SORTABLE (sortable)' failed
saying that the treemodel is not sortable.
This problem seems to be surmountable in PyGtk as suggested here. The idea is to stack a ListStore, a TreeModelFilter and a TreeSortFilter one inside the other and feed the last one as the model for the treeview.
However this trick does not seem to be working in Python Gtk+3. When I try
self.modelfilter = self.liststore.filter_new()
self.modelfilter.set_visible_func(\
self._visible_filter_function)
self.sorted_and_filtered_model = \
Gtk.TreeModelSort(self.modelfilter)
self.treeview.set_model(self.sorted_and_filtered_model)
it complains
Gtk.TreeModelSort(self.modelfilter)
TypeError: GObject.__init__() takes exactly 0 arguments (1 given)
Now I tried to get a instance of Gtk.TreeModelSort with no arguments. But this instance does not have any set_model method.
I am lost here.
Is there another way to set the model for Gtk.TreeModelSort? Or is there a totally different way to get a filtered and sortable treemodel object that can be displayed in a treeview?
>>> from gi.repository import Gtk
>>> mymodel = Gtk.ListStore()
>>> Gtk.TreeModelSort(model=mymodel)
<TreeModelSort object at 0x1d4d190 (GtkTreeModelSort at 0x1f0d3f0)>
In my opinion PyGObject is not ready yet. It has no browsable documentation, some things are not instrospected yet and in particular this:
Sometimes a widget work with Gtk.MyWidget(attr=foo), like this one.
Sometimes with Gtk.MyWidget.new_with_label('Foo'), like buttons. Yes, Gtk.MyWidget(label='Foo') doesn't work.
Kind regards

Silverlight databinding with IronPython and Datagrid

We've been successfully using clrtype with IronPython 2.6 and
Silverlight for databinding, based on the example provided by Lukás(:
http://gui-at.blogspot.com/2009/11/inotifypropertychanged-and-databinding.html
We create the binding when we create the datagrid columns programatically. Because we are using IronPython some of the static databinding techniques you would normally use with C# don't work.
I've been trying (and failing) to get a column in the grid show
different colors based on databinding.
I've got the colored bubble showing in the grid, but can't get
databinding to the color to work. First the basics.
This is the xaml for the bubble with a fixed color:
<DataTemplate xmlns='http://schemas.microsoft.com/client/2007'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Ellipse Stroke="#FF222222" Height="15" Width="15">
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop x:Name="bubbleColor" Offset="0.694"
Color="#FF00FF40" />
<GradientStop Color="#FFE6E6E6"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
I can add a column based on this template very simply. The loadXaml function is a thin wrapper around XamlReader.Load:
from com_modules.loadxaml import loadXaml
from System.Windows.Controls import DataGridTemplateColumn
column = DataGridTemplateColumn()
column.CellTemplate = loadXaml('templatecolumn')
column.Header = 'Bubble'
grid.Columns.Add(column)
If I try to naively specify a binding in the xaml then I get a
PARSER_BAD_PROPERTY_VALUE when I attempt to load the xaml (so no hope of
setting up the binding after load):
<GradientStop x:Name="bubbleColor" Offset="0.694" Color="{Binding color}" />
One approach I tried was to create a ValueConverter. Here is the
skeleton of the class I created:
from System import Type
from System.Globalization import CultureInfo
from System.Windows.Data import IValueConverter
class ColorConverter(IValueConverter):
_clrnamespace = "Converters"
__metaclass__ = clrtype.ClrClass
#clrtype.accepts(object, Type, object, CultureInfo)
#clrtype.returns(object)
def Convert(self, value, targetType, parameter, culture):
pass
#clrtype.accepts(object, Type, object, CultureInfo)
#clrtype.returns(object)
def ConvertBack(self, value, targetType, parameter, culture):
pass
As there is a _clrnamespace specified I thought I might then be able to use this converter in xaml. Trying to reference the ColorConverter class in the Converters namespace in a resources dictionary again causes blow ups when loading the xaml.
Setting this up programatically would be ideal. Anyone got any ideas?
I don't know anything about IronPython, but I know that you cannot bind to a Color in Silverlight, regardless of the language used. This has caused me many grievances. In Silverlight 3 you can only bind properties on a FrameworkElement, and since GradientStop is a DependencyObject, it will not work. The good news is that Silverlight 4 will get rid of that limitation and allow you to bind properties on DependencyObject. I haven't tried it though, so I cannot say for sure. More info here:
http://timheuer.com/blog/archive/2009/11/18/whats-new-in-silverlight-4-complete-guide-new-features.aspx#dobind
At the moment, what you could do is to bind the Fill property on the Ellipse instead. But then you will have to create the entire LinearGradientBrush in your converter code, so it's a bit complicated.

Categories

Resources