是否可以从主线程显示和更新进度条?

时间:2016-02-20 01:26:52

标签: user-interface dialog dm-script

我想提出一个进度条来显示一个冗长的例行程序的状态。它非常直接从后台线程启动带有进度条的对话框。但是,是否可以从"前景"处理?这个想法是显示进度状态,但阻止用户使用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();

1 个答案:

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