Having a drawn object remain visible while keyboard input

Hi,

I am having some trouble with drawing in the following code and it’s probably because I don’t understand it that well.

...
TPolyLine3D *line = new TPolyLine3D(...) 

while(!file.eof()){
     file >> s0 >> s1 >> s2 >> s3 >> s4 >> s5 >> s6 >> s7 >> sec >> microsec;

     if(count==fev+1)
       break;
     if(count==sev)
       dispon=1;


     if(dispon){
       line->Draw();
       //p1->WaitPrimitive();
       input=Getline("type <s> to save: ");
       cout << "type <s> and then <return> to save: ";
       cin >> input;
       if(input=="s"){
         recordfile << infile << "  " << count << endl;
       }
       c1->WaitPrimitive();
     }
     count++;
   }

....

Please imagine that I want to go into the above loop with some object to draw into the current pad “p1” which was made somewhere above and then p1->cd();. The behavior that I want is after the line->Draw() happens the image persists while I request the keyboard input. After the input the loop continues (saving some input to the stream “recordfile” if I type “s”). They key is that if I use the p1->WaitPrimitive() or even c1->WaitPrimitive() (c1 is the canvas where all of this is happening), the image remains until I double-click on the pad, at which time the next image is drawn by the action of the while loop.

How can I have the image remain while I wait for keyboard input?

Note that “dispon”, “fev” and “sev” are just variables I use to determine which loop elements to print, and can be ignored here. Basically I am looping through a file with a number of events but want to be able to specify a range of events to examine visually, then record their event numbers if the user decides so.

Can you send a small script we can run reproducing the problem ?

Sure. Actually I think I’ve solved this problem in trying to make you an example script:

#include <iostream>
using namespace std;
void polyLineRefresh(Int_t n=5)
{

  TCanvas *c1 = new TCanvas("c1","PolyLine3D",200,20,700,700);

  TPad *p1 = new TPad("p1","p1",0.1,0.1,0.9,0.9,0,4,1);

   //http://root.cern.ch/root/html/TView.html#TView:CreateView
   TView *view = TView::CreateView(1);
   //view = TView::CreateView(1);
   view->SetRange(-48,-48,-48,48,48,48);
   view->RotateView(90.0,0.0);


   TPolyLine3D *test = new TPolyLine3D(n);
   int col=1;
   test->SetLineColor(col);

   float r=10.0,x,y,z=0,theta;
   theta=0.0;
   string input;

   for(int i=0;i<n+1;i++){
      //cout << theta << endl;
      x=r*cos(theta); y=r*sin(theta); test->SetPoint(i,x,y,z);
      theta += 3.14159*2/n;

      test->Draw();
      c1->Update();
      //input=Getline("type <i> increment color: ");
      cout << "type <i> and then <return> to increment color: ";
      cin >> input;
      if(input=="i"){
         col++;
         test->SetLineColor(col);
      }
   }

}

Previously I did NOT have the c1->Update() call. I just did test->Draw(). The symptom was that it did not draw at every step in the loop, hence did not “refresh” properly. I made an input above which allows one to increment the color of the produced n-gon.

I would be happy to hear if there is a better way to do this kind of thing…accept keyboard input and then update visualization after a pause.
polyLineRefresh.C (966 Bytes)

The way you did it is correct. A gPad->Update() is needed. The only issue it that root is stuck on the keyboard input. You can also use WaitPrimitive(). There is plenty of examples in the forum (just search the string “WaitPrimitive”). You can also do a little GUI but it is more complex.