Barra de progreso mostró cómo hacer una barra de progreso. @abmayfield pregunta en "no responder" frente a "seguir pensando" me impulsó a volver a visitar esto. Aquí hay otra toma, que incluye un botón para cancelar.
no cancelado
Botón Cancelar presionado.
progressBarWidth = 500;
progressUpdatesSeconds = 1 / 4; // 1/2 sec updates -> 1300ips, 1/30 -> 1000ips (1/4 compromise speed vs appearance)
cancel = 0; // clear the cancel flag
New Window( "Progressbar demo", //
V List Box( //
cats = Text Box( "" ), // output from the work function
t = Text Box( "", <<SETWRAP> ^workCalls/runSeconds^ ips" ) );
t << updatewindow; // this works without the wait
);
totalCats = 0;
dowork = Function( {},
x = "";
For( i = 1, i <= 1000, i += 1, x = x || "." );
totalCats += 1000;
cats << settext( Eval Insert( "total concatenations=^totalCats^" ) );
);
While( runSeconds < limitSeconds & !cancel, // change this to represent the work you are doing
// do some work, simulated by concatenating strings...
dowork();
// update the progressbar
workCalls += 1;
nowMicroSeconds = HP Time();
// how often does it need to update on the screen?
If( (nowMicroSeconds - recentUpdateMicroSeconds) / 1e6 > progressUpdatesSeconds,
// in this example I'm using a fixed time duration of "limitSeconds" to represent the
// amount of work to be done. And "runSeconds" to represent the amount of work done so far.
// Usually you'll have something other than time: number of rows in a table perhaps, or
// number of categories to make reports for. As long as you know how many total and how
// many completed, you can compute this fraction...
updateProgress( runSeconds / limitSeconds ); // change this to represent the fraction of work finished
recentUpdateMicroSeconds = nowMicroSeconds;
Wait( 0 ); // this wait is needed to let the cancel button work
);
runSeconds = (nowMicroSeconds - startMicroSeconds) / 1e6;
);
If( cancel, // test the cancel flag
Beep(); // audio flag
left << color( "dark red" ); // visual flag something is awry
right << color( "red" );
, //
updateProgress( 1.0 ); // people like to see the bar go to 100%
);
cancelButton << setbuttonname( "Close" ); // visual flag the button function is changed
cancelButton << setscript( (cancelButton << closewindow) ); // and what to do if the button is pressed
</SETWRAP>
Al probar entre JMP 15 y 16, noté que 16 es un lote ¡más rápido en esta carga de trabajo de concatenación de cadenas! ¡Buen trabajo!
Editar: si JMP está ejecutando una plataforma que no tiene su propia barra de progreso cancelable y se ejecuta durante mucho tiempo, esto no ayudará. El soporte técnico sería un buen lugar para solicitar el soporte de la plataforma para una barra de progreso. Sin él, no hay forma (salvo cerrar JMP por la fuerza) para detenerlo hasta que esté listo.
Gracias @Craige_Hales ! Sucedió que necesitaba una barra de progreso (o algo similar) para uno de mis scripts, así que tomé esto y lo modifiqué un poco para satisfacer mis necesidades. Lo convertí en una clase (soy muy principiante con las clases de JMP y las clases en general) para práctica y porque sentí que podía encajar en uno. También agregué documentación que se puede analizar con Natural Docs.
Código:
Ver más...Names Default To Here(1);
//Modified from https://community.jmp.com/t5/Uncharted/Progress-Bar-with-Cancel-Button/ba-p/433560
Define Class(
/************************************************************************************************
Class: ProgressBar
---Prototype---
ProgressBar(int max_iteration = 1, int ith_iter_to_print = 5)
---------------
Creates brogress bar with cancel button. Pressing cancel will return 1 from
update(current_iteration) method this can be used to break out of loop.
Prototype:
> pb = New Object(ProgressBar(<max_iteration = 1>, <ith_iter_to_print = 5>)
> pb << update(current_iteration)
> pb << close()
Parameters:
max_iteration - Maximum iterations for the progress
ith_iter_to_print - ith values to print. Modulo(current_iteration, ith_iter_to_print)
Examples:
----------JSL-----------
pb = New Object(ProgressBar(10, 1));
For(i = 1, i <= 10, i++,
cancel_pressed = pb << update(i);
If(cancel_pressed == 1,
break();
);
wait(1);
);
pb << Close;
pb << Delete Class;
------------------------
************************************************************************************************/
"ProgressBar",
progressBarWidth = 500;
cancel = 0;
_init_ = Method({max_iteration = 1, ith_iter_to_print = 5},
this:cancel = 0;
this:max_iteration = max_iteration;
this:window_ref = this:create();
this:i_to_print = ith_iter_to_print;
this:start_time = HP Time();
);
create = Method({},
aa_nw = Associative Array();
nw = New Window("Gage Progress", //
V List Box(
Align("center"),
// cats = Text Box(""), // output from the work function
t = Text Box("", <<setwrap(500)), // status of the progressbar
H List Box( // Duct tape has a light side and a dark side. So does the progressbar.
left = Spacer Box(size(0, 10), color("light green")), //
right = Spacer Box(size(progressBarWidth, 10), color("dark green")), //
<<padding(5, 5, 5, 5), // gray wrapper
<<backgroundcolor("dark gray") //
), //
cancelButton = Button Box("Cancel", <<Style("Toggle")) // sets the cancel flag
)
);
aa_nw["nw"] = nw;
aa_nw["t"] = t;
aa_nw["left"] = left;
aa_nw["right"] = right;
aa_nw["cancelButton"] = cancelButton;
Return(aa_nw);
);
get_cancel_status = Method({},
Return(this:window_ref["cancelButton"] << get)
);
update = Method({current_iteration},
If(Modulo(current_iteration, this:i_to_print) == 0 | current_iteration == 1,
Try(
leftsize = Round(progressBarWidth * (current_iteration / this:max_iteration));
rightsize = progressBarWidth - leftsize;
this:window_ref["left"] << width(leftsize);
this:window_ref["right"] << width(rightsize);
cur_time = Round((HP Time() - this:start_time) / 10^6, 3); //could use formatting to keep same length
this:window_ref["t"] << settext(Eval Insert("Iteration ^current_iteration^ of ^this:max_iteration^. Total runtime: ^cur_time^s"));
// this:window_ref["t"] << settext(Eval Insert("^current_iteration^ iterations in ^char(runSeconds,6,3)^ seconds -> ^workCalls/runSeconds^ ips"));
this:window_ref["t"] << updatewindow; // this works without the wait
cancel_status = this:get_cancel_status();
, //lazy handling with catch
cancel_status = 1;
show(exception_msg);
);
);
/* If(cancel_status == 1,
this:window_ref["left"] << color("dark red");
this:window_ref["right"] << color("red");
);
*/
Return(cancel_status);
);
close = Method({},
Try(
this:window_ref["nw"] << Close Window
)
);
);
pb = New Object(ProgressBar(10, 1));
For(i = 1, i <= 10, i++,
cancel_pressed = pb << update(i);
If(cancel_pressed == 1,
break();
);
wait(1);
);
pb << Close;
pb << Delete Class;
Write(); Los documentos naturales se verán así:

Quiere ser empaquetado, gracias!
En su ejemplo, pb<
También has señalado algo que me perdí en Cómo usar Definir clase : Pensé que necesitaba diseñar a los miembros de la clase explícitamente en el prototipo de clase definida, pero este: puede crearlos también.
Define Class("bubble",
//not needed: m_xpos = .;
_init_ = Method( {x}, <BR />//because using explicit this: ...
this:m_xpos = x;