2016-02-20 1 views
1

Je voudrais poser une barre de progression pour montrer l'état d'une longue routine. Il est plutôt simple de lancer une boîte de dialogue avec une barre de progression à partir d'un fil d'arrière-plan. Cependant, est-il possible de le faire à partir d'un processus de «premier plan»? L'idée est de montrer l'état d'avancement mais empêche l'utilisateur de faire quoi que ce soit avec DM. La palette de gadgets Progress intégrée (accessible via la commande de script OpenAndSetProgressWindow) sert mon but, mais je veux avoir une interface plus sophistiquée et aussi afficher plus d'informations. Ce qui suit est un exemple de script. Comme nous pouvons le voir, lorsque vous posez la boîte de dialogue ProgressBar à partir d'un processus de premier plan, elle n'est pas du tout mise à jour.Est-il possible d'afficher et de mettre à jour une barre de progression à partir du thread principal?

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

Répondre

1

Lorsque vous exécutez la forme DLGSetProgressBar() un fil conducteur, vous avez besoin de forcer une mise à jour de la boîte de dialogue fenêtre avec ValidateView()

-à-dire dans votre script ci-dessus, vous pouvez le faire soit dans la boucle principale :

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

Ou vous pouvez le faire dans la mise à jour méthode:

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