2016-02-20 176 views
1

我想提出一个进度条来显示冗长程序的状态。从后台线程启动带进度条的对话框非常简单。然而,是否有可能从“前景”过程中这样做?这个想法是显示进度状态,但阻止用户使用DM做任何事情。是否可以从主线程显示和更新进度条?

内置的小工具的进展调色板(通过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(); 

回答

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(); 
    }; 

或者你可以在更新方法做到这一点:

void SetProgress(object self, number fraction) { 
    self.DLGSetProgress(identifier_progressBar, fraction); 
    self.ValidateView() 
};