我想提出一个进度条来显示一个冗长的例行程序的状态。它非常直接从后台线程启动带有进度条的对话框。但是,是否可以从"前景"处理?这个想法是显示进度状态,但阻止用户使用DM做任何事情。
内置的Progress小工具调色板(可通过 OpenAndSetProgressWindow 脚本命令访问)符合我的目的,但我希望拥有更高级的界面并显示更多信息。以下是一个示例脚本。我们可以看到,当从前台进程中构建ProgressBar对话框时,它根本不会更新。
class ProgressBar : UIFrame {
number true, false;
string Identifier_Status, identifier_progressBar;
string panel_name;
number token;
//
ProgressBar(object self) {;
true=1; false=0;
identifier_progressBar = "Progress_Bar";
Identifier_Status = "Progress_Status"
result("Script object \"ProgressBar\"[" + self.ScriptObjectGetID().hex() + "] constructed\n" );
};
~ProgressBar(object self) {;
result("Script object \"ProgressBar\"[" + self.ScriptObjectGetID().hex() + "] destructed\n\n" );
};
//
void SetProgress(object self, number fraction) {
self.DLGSetProgress( identifier_progressBar, fraction );
};
void UpdateStatus(object self, string status ) {
self.LookUpElement(Identifier_Status).DLGTitle(status);
};
void Terminate(object self) {
panel_name.CloseGadgetPanel();
// token.UnregisterScriptPalette();
panel_name.UnregisterScriptPalette();
};
void init(object self, string title, string prompt) {
panel_name = title;
// build main dialog tag group
TagGroup tgDLG = DLGCreateDialog( panel_name );
// create UIFrame elements
TagGroup tgProgressBar = DLGCreateProgressBar(identifier_progressBar).DLGFill("X");
TagGroup tgStatus = DLGCreateLabel(prompt).DLGWidth(40).DLGIdentifier(Identifier_Status);
// build position
TagGroup tgPositon = DLGBuildPositionFromApplication();
tgPositon.TagGroupSetTagAsString( "Width", "Wide" ); // Narrow, Medium, Wide;
tgPositon.DLGSide( "Left" );
tgDLG.DLGPosition(tgPositon);
// assemble dialog
tgDLG.DLGAddElement(tgStatus);
tgDLG.DLGAddElement(tgProgressBar);
// initialize and display
self.super.init( tgDLG );
token = self.RegisterScriptPalette(panel_name, panel_name);
panel_name.OpenGadgetPanel();
//
return;
};
};
class main : Thread {
object obj;
main(object self) {
obj = alloc(ProgressBar);
result("Script object \"main\"[" + self.ScriptObjectGetID().hex() + "] constructed\n" );
};
~main(object self ) {
result("Script object \"main\"[" + self.ScriptObjectGetID().hex() + "] destructed\n" );
};
void RunThread(object self) {
obj.init( "Progress bar test", "<status>" );
string msg1, msg2, msg3;
number time = 5, interval = 0.1, nSteps = time/interval;
for( number idx = 1; idx <= nSteps; idx++) {
//
msg1 = "Processing step:";
msg2 = " ";
msg3 = "#" + idx + " of " + nSteps;
//
OpenAndSetProgressWindow( msg1, msg2, msg3 );
//
obj.UpdateStatus( msg1 + msg2 + msg3 );
obj.SetProgress( idx/nSteps );
yield();
sleep(interval);
};
msg1 = ""; msg3 = "";
msg2 = "completed"
OpenAndSetProgressWindow( msg1, msg2, msg3 );
obj.Terminate();
};
};
if( TwoButtonDialog( "Show and update progress bar as", "background thread", "forground process") ) alloc(main).StartThread();
else alloc(main).RunThread();
答案 0 :(得分:1)
当您运行DLGSetProgressBar()
表单主线程时,需要使用ValidateView()
即。在上面的脚本中,您可以在主循环中执行此操作:
void RunThread(object self) {
obj.init( "Progress bar test", "<status>" );
string msg1, msg2, msg3;
number time = 5, interval = 0.5, nSteps = time/interval;
for( number idx = 1; idx <= nSteps; idx++) {
//
msg1 = "Processing step:";
msg2 = " ";
msg3 = "#" + idx + " of " + nSteps;
//
OpenAndSetProgressWindow( msg1, msg2, msg3 );
//
Result("\n Step "+idx)
obj.UpdateStatus( msg1 + msg2 + msg3 );
obj.SetProgress( idx/nSteps );
obj.ValidateView() // <<<<<<<<<<<<<<<<<< HERE
yield();
sleep(interval);
};
msg1 = ""; msg3 = "";
msg2 = "completed"
OpenAndSetProgressWindow( msg1, msg2, msg3 );
obj.Terminate();
};
或者您可以在update-method中执行此操作:
void SetProgress(object self, number fraction) {
self.DLGSetProgress( identifier_progressBar, fraction );
self.ValidateView()
};