1

我想设置一个进度条来显示冗长例程的状态。从后台线程启动带有进度条的对话框相当简单。但是,是否有可能从“前台”过程中做到这一点?这个想法是显示进度状态,但阻止用户使用 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();
4

1 回答 1

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()
};
于 2016-02-20T13:36:04.640 回答