Purpose of Bokeh custom JS callbacks - bokeh

This question is may be a bit too general. Why do the JS callbacks exist in Bokeh?
Why would you want to use a CustomJS callback (with our without a Python function) instead of a regular event handler function for a widget?
Here is the guide for the CustomJS callbacks: https://docs.bokeh.org/en/latest/docs/user_guide/interaction/callbacks.html#customjs-for-range-update
But why go through that when you can have the same widget and use an event handler function as seen here: https://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html#slider
In the example at the last link you can make an event handler function run on every change in the input box without getting CustomJS callbacks involved:
def my_text_input_handler(attr, old, new):
print("Previous label: " + old)
print("Updated label: " + new)
text_input = TextInput(value="default", title="Label:")
text_input.on_change("value", my_text_input_handler)
What confuses me is that I feel like you should be able to make an advanced event handler for a widget by simply using the last method without using CustomJS callbacks.
Many of the examples in the CustomJS guide (first link) deal with interactions with widgets like the slider.

You can use CustomJS callback to have interactions in static html files. And like any language translation tool, the from_py_func method is going to be limited to simple python functions.
Also some object properties are internal to bokehjs and can only be accessed via CustomJS callback like Tool.active

Related

How to link bokeh widget parameters with cb_obj.get() in js callbacks

I've been looking over the bokeh doc page on Adding interactions and am completely mystified as to how parameters from widgets are passed to the cb_obj.get() function in javascript callbacks.
I can't understand how the arguments to the cb_obj.get() function are chosen, e.g.:
cb_obj.get('value')
cb_obj.get('selected')['1d'].indices
cb_obj.get('data')
cb_obj.get('start')
cb_obj.get('end')
The arguments seem to look like standard terms, but I can't see where they are defined.

Angular-like client side data binding and reactivity with Meteor?

I'm trying to wrap my head around Meteor's way of dealing with reactivity and I want to make sure I've got some concepts right.
Take the follow reactivity example:
A user types something into a form field. The thing that he is typing is instantly displayed somewhere else on the page, as the user is typing, letter by letter. An instantaneous duplication.
From what I know about Angular, this is a very common example of reactivity. Angular binds the input directly to the output on the client side. There's nothing in between.
Correct me since I could be wrong, but Meteor can do this, but the input would first need to be captured and stored into a Mongo + MiniMongo DB (perhaps only as a collection in local storage), there would need to be a subscribe step, and those values would then be read and displayed on the page.
Is there a way to directly bind an event on the front end to another thing on the front end like Angular does?
Is this right? For Meteor to have the front-end-only reactivity of Angular it must first go through the intermediary of a collection, meaning extra code would be necessary to accomplish this compared to Angular?
The example in the Meteor Docs:
Deps.autorun(function () {
Meteor.subscribe("messages", Session.get("currentRoomId"));
});
So here, when the data of currentRoomId changes, the function is reactive to that data change and the function runs (in this case Meteor subscribes to messages).
Using Session variables is the only way I see of possibly binding two parts of a view together directly. Are there other ways?
Meteor's client-side reactivity system (Deps) is not coupled with its live MongoDB syncing. You can use it with any reactive data source which implements the right interface, including data sources which are entirely client-side. For example, you can use the built-in Session object. This is just a client-side key-value store with support for Meteor's reactivity, and you don't have to do any publish or subscribe to use it.
This standard way to do this sort of thing looks something like this:
<input id="field" value="{{fieldValue}}">
Template.form.fieldValue = function () {
return Session.get("fieldValue");
};
Template.form.events({
"input #field": function (evt) {
Session.set("fieldValue", $(evt.currentTarget).val());
}
});
Now the Session variable fieldValue is synced up to the form field. You can call Session.get("fieldValue") in some helper and that template will re-render when the user types in the form field. And if you call Session.set("fieldValue", "blah") then the form field will update itself.
As for your edit: You can make your own reactive data sources using Deps.Dependency, or you could meteor add reactive-dict although that's not documented. There may be packages on Atmosphere.

Access python function from javascript in QWebView

I am writing a Python/PyQt4 application that generates and displays a page in a QWebView widget. The page includes javascript code that I would like to be able to call functions returning data from the python application.
So far I can call functions that do not return data (using the pyqtSlot decorator), and call functions that do take parameters by exposing them as properties (using the pyqtProperty decorator). What I haven't worked out how to do is to call a python function with parameters, that returns data.
The question 9615194 explains how to do this from C++, but I cannot see how to transfer this to PyQt4.
I suspect you're not using the result= keyword to specify the return value in your pyqtSlot decorator?
#pyqtSlot(str, result=str)
def echo(self, phrase):
return self.parent().echo(phrase)
I ran afoul of this myself recently. No errors are generated if you omit result=, the method just silently returns nothing. Pretty maddening 'til I figured it out. See my answer to this question for a worked example.

Flex's FileReference.save() can only be called in a user event handler -- how can I get around this?

I need to call FileReference.save() after a web service call has completed, but this method has a restriction: "In Flash Player, you can only call this method successfully in response to a user event (for example, in an event handler for a mouse click or keypress event). Otherwise, calling this method results in Flash Player throwing an Error exception." (from the documentation here)
This restriction is a bit vague. Does it mean that I can only call the FileReference.save() method from within an event handler function that is registered as a listener for certain types of user events? If so then exactly which user events are valid? (Perhaps there's an event that will never be dispatched by user interaction with my application and I could register an event handler function for that event type and make the save() call from within that function?)
My difficulty is that I can't safely call the FileReference.save() method until my web service returns with the data that will be used as the argument of the FileReference.save() method call, so the event that triggers the FileReference.save() call is actually a ResultEvent rather than a user event, and I'm leery of dispatching a new (faux) user event type in order to be able to trigger the FileReference.save() call unless it's definitely a user event that would never be dispatched as a result of actual user interaction with my application.
In a nutshell what I'm doing now is this: I have a function that is registered as a handler for a button click. In this function I make my web service call to fetch data from the server. I also have a result handler function which gets invoked when the web service call completes, and it's in here that I want to call the FileReference.save() method since it's at this point that I know that the data is ready to be saved to a file. But the aforementioned restriction is blocking me from doing this -- I get an error:
Error #2176: Certain actions, such as those that display a pop-up window,
may only be invoked upon user interaction, for example by a mouse click
or button press.
I've tried many things to get around this such as creating a second mouse click event handler function with the FileReference.save() call within and calling it after a timeout interval (to give the web service time to complete), but I keep running into the same error -- maybe that approach doesn't work since the second function isn't registered as an event listener for the event type used as its argument.
I'm new to Flex development so perhaps I'm just not thinking about this in the right way. If anyone can suggest another approach I'd really appreciate it. Thanks in advance for your comments or suggestions.
--James
Adobe does this as a sort of security measure to ensure users are the ones messing with files rather than potentially harmful code. My understanding is that they enforce this by only allowing handlers of (click?) events that originate from UI components to execute the FileReference methods, so generating your own events programmatically will not work, although I have not tried to verify this. Unfortunately the best resolution I've found is to re-work the UI a bit to conform to this constraint. In your particular situation, you could make this a two click process with a button that says something like "Prepare Download", which changes to "Download File" after the web service is complete. This is less than ideal from a user perspective, but I don't think there's much else that can be done unless you can somehow complete your web service call prior to displaying the button that triggers the FileReference.save() call.
After struggling for that for well, a couple hours I found a workaround: you can use both mouseDown AND mouseUp events instead of just click.
For instance:
s:Button
mouseDown="prepare_PDF()"
mouseUp="save_PDF()"
Works fine for me!
Happy coding!
--Thomas
As a workaround I used the ExternalInterface class. I created a javascript function with this code
function downloadFile (url) {
window.open(url);
}
An in AS3 I call
var url = 'www.example.com/downloadfile.php?file_id=xxx';
ExternalInterface.call('downloadAttachmentFile', url);
So with that I transfer the file handling to JS/HTML.
This is a comment on Thomas' answer (I don't have enough XP to comment yet): The mousedown and mouseup workaround works nicely. Just a note that if you make any changes in prepare_PDF() that need 'undoing' in save_PDF(), then its a good idea to call that code on the mouseout event as well, since there might be a case that the user mousedown's on the button, but then moves the mouse away from the button.
This was particularly relevant for my case, in which we increase the size of a watermark on an image when the user clicks the download button (that triggers the .save() call). I reduce the size of the watermark down to normal on the mousedown and mouseout events.
I had this same issue, I chose to use flash.net methods. Call flash.net.navigateToURL(url); from an actionscript or navigateToURL(url); from mxml.
What i do to solve this is to show an alert message with an anonymous function so i don't have to create a button.
Alert.show("Do you wish to download the file?", "Confirm", Alert.OK | Alert.CANCEL, this, function (eventObj:CloseEvent):void {
if (eventObj.detail == Alert.OK) {
fileReference.save(zipOut.byteArray, dateFormater_titulo.format(new Date ()) + ".zip");
}//if
}/*function*/, null, Alert.OK);

PyQt, Qt, one event handler working with many items

I have a couple of checkboxes on my form, and I don't want to write separate event handler for each, because they all will implement the same logic. Instead I want to write just one event handler that will know about what checkbox has been clicked.
E.g. in Delphi I can use it this way:
function click_handler(sender):
begin
checked_box := sender.tag;
end;
Here I remember current checked box number in some variable (tag property was manually set in Delphi IDE).
I searched and can't find how I can implement this using Qt, because event handlers don't have sender argument.
I implemented it like this, but it's not convenient:
# assign handlers (n assignments)
checkbox_1.clicked.connect(self.cb_1_click)
...
checkbox_<n>.clicked.connect(self.cb_<n>_click)
# separate handler for each check box (n functions, doing the same stupid work)
def cb_1_click:
self.cb_click(sender=1)
...
def cb_<n>_click:
self.cb_click(sender=n)
# main check box click logic (1 function)
def cb_click(sender):
# do something common for all checkboxes
Thank you.
You may use QObject::sender() in slots to find out who emitted the signal.
Also you might want to check out QSignalMapper which is intended exactly for solving these problems.

Resources