create an observe handler for multiple ipywidgets - jupyter-notebook

I have to create a collection of buttons dynamically based on lists of words.
I create them with a class.
Then I have to dynamically see how many of them are clicked by the user and act accordingly (get the collection of clicked buttons per column).
My problem is how to deal with the event handlers.
I can not make my mind around as how to deal collectively with all the buttons created. I basically need a listener that every time a change happens looks how many buttons are clicked and of course click and unclick the corresponding buttons.
This is so far my code:
class verticalButtons():
def __init__(self,concepts):
self.verticalbuttons = self.create_buttons(concepts)
def create_buttons(self,concepts):
import ipywidgets
wd_buttons = []
for i,concept in enumerate(concepts):
newbutton = ipywidgets.Button(description=concept,
button_style='success')
wd_buttons.append(newbutton)
verticalbox = VBox(wd_buttons)
return verticalbox
basically passing a list of words to the class creates a VBox with the buttons.
mylist1 = ['1first','1second','1third']
mylist2 = ['2first','2second','2third','2fourth']
one = verticalButtons(mylist1)
two = verticalButtons(mylist2)
button_columns = widgets.HBox([one.verticalbuttons,two.verticalbuttons])
display(button_columns)
the result is as follows:
Some idea? I don't even need the code, but just kind of the idea how to deal with it.
thanks.

Related

Dynamically create widgets based on records in a datasource

(Apologies in advance for the poorly worded question.)
Not sure if this is even possible - Have not been able to find any documentation regarding this...
I have a datasource whose records contain fields of information on certificates.
For each record in the data source I want to create a label widget on a specified panel. (The panel has been already been created on an app maker page.)
Going to put some pseudo code below to show what I am hoping to achieve:
var length = app.datasources.Certificates.items.length;
var records = app.datasources.Certificates.items;
for (var i =0; i <length; i++){
app.pages.A_Edit_Certificate_Requirements.descendants.Panel1.createNewWidget(label,text = records[i].Certificate_Name)
}
.newWidget(type of widget, property of widget to configure) is the pseudo portion.
Anyone know if something like this is even possible?
Reason I am looking to do it via this method is to keep the page as dynamic as possible.
If you do want to proceed with creating the labels dynamically yourself here would be some sample code to get the same accomplished. In order for this to work your panel datasource would need to be set to 'Certificates' and the code would need to be attached to the panel's onDataLoad event:
widget.datasource.items.forEach(function(item) {
var node = document.createElement('div');
node.className = 'app-Label';
node.style.margin = '8px';
node.textContent = item.Certificate_Name;
widget.getElement().appendChild(node);
});

JavaFX Observable where the value can be swapped

I am writing a small experimental desktop application. Basically it has the options to display a list of recipes and detailed information about a single recipe.
To accomplish that i implemented a class called RecipeContext that stores a ObservableList<Recipe> that i bind to a TableView, so the view gets automatically updated if i add to, or remove from the collection.
I want something similar for the single recipe, an Observable where i simply have to change the contained recipe and have the view automatically update to display the new recipe information.
To make this a bit more clear, i want something like this:
SingleObservable<Recipe> detailedRecipe = new SingleObservable<>(new Recipe("A"));
detailedInformationController.bindRecipeObservable(detailedRecipe);
// Recipe A is displayed
detailedRecipe.set(new Recipe("B"));
// View is notified about the change and displays Recipe B
Is there a class that does that?
SimpleObjectProperty will do what you want.
SimpleObjectProperty<Recipe> detailedRecipe = new SimpleObjectProperty<>(new Recipe("A"));
...
detailedRecipe.set(new Recipe("B"));
http://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/SimpleObjectProperty.html

call ds_list from diffrent object error

I have created a textbox object and in its create event it creates list like
lines = ds_list_create();
in step event of textbox I use ds_list_add(lines, "line one");
and it works fine.
Now I have a diffrent object that try to call ds_list_add(Textbox.lines, "line from diff object");
but on running it gives error about var not set before reading. i tried also to change to global.list = ds_list_create(); and still same problems.
can someone explain how to call ds_list from diffrent object.
You can call ds_list_* functions right like you did. Just, you must make sure the data structures a function is referring to does actually exists.
I tried the following for testing purposes. Create two objects, objTextBox and objOther and set their events as follows.
For object objTextbox:
Create Event
list = ds_list_create();
Press 'Space' Event
var str = get_string("I'm objTextbox:","");
ds_list_add(list,str);
Draw Event
for (var i=0;i<ds_list_size(list);i++)
draw_text(10,10+15*i,string(ds_list_find_value(list,i)));
For object objOther:
Press 'Shift' Event:
var str = get_string("I'm objOther:","");
ds_list_add(objTextbox.list,str);
Now add them to a room, and make sure first object to be created is objTextbox, which is the one creating the ds_list. Run.
When dealing with data structures, always make sure they were created before working with them.

CodeName One about lists

I have a problem I want to use the list and when I click on a component of the list it take me to another form (make an action) meaning if I click on an item from the list depending on the selected index it takes me to another form.
Is this in a GUI builder app or manual app?
For GUI builder use the action event callback for the list see: http://www.codenameone.com/how-do-i---handle-eventsnavigation-in-the-gui-builder--populate-the-form-from-code.html
Then get the index/selected item using:
int index = list.getSelectedIndex();
Object value = list.getSelectedItem();
Then you can show the form you want using:
showForm("FormName", null);
In handcoded apps you can get the selected item/index in exactly the same way then do something like:
form.show();
To show a specific form.

Trigger action on completion of drag action

I'm trying to allow items from a QListWidget to be dragged to a "Trash" (A subclassed widget which accepts drops and does nothing with them).
I know that if I setDropAction(Qt.MoveAction), the items I am removing from the source will be automatically deleted. This works correctly.
My problem is that I also need to trigger an action that updates other widgets who depend upon the contents of the source.
It seems to me that the dropEvent happens before any items are actually removed from the source. I'm having a terrible time trying to figure out this problem. I've thought of two possible solutions:
Find a way to embed the references to the actual QListWidgetItems that are being dragged in the event's QMimeData. This would allow me to do the deletions by hand, before I trigger updates.
Figure out how to wait until the source has been automatically cleared, but I can't find any signals that fire when items are removed from a list automatically.
Aha!
The key I was missing was the mimeData method. This method is called when a drag is started, and in it I am passed a list of all files being dragged.
I first built the meta object to be returned, then I deleted the files being dragged from the list, and called the refresh action that I needed.
Here's an example:
def mimeData(self, items):
m = QMimeData()
m.setUrls([QUrl(i.url) for i in items])
# Clean up the list:
[self.files.takeItem(self.files.indexFromItem(i).row()) for i in items]
self._update_meta()
return m

Resources