Pad with primitives painting during executing

_ROOT Version: 6.18

Hello,

I try to paint pads with some primitives on a canvas. The following code really paint the primitives, but menus bar appears only after finishing the execution of a script. Also I can’t open the context menu on primitives and axes (although if I try to change axes range before execution finishing, the changing appears after finishing).
Can I open the context menu and other things before execution finishing?

#include "root/TCanvas.h"
#include "root/TF1.h"
#include "root/TH1.h"
#include "root/TPad.h"
#include "root/TList.h"
#include "root/TCollection.h"


int canvas()
{
	TCanvas *c;
	TPad *p1, *p2;
	TList *list;
	TF1 *f1, *f2;
	int k;
	char strb[32];

	k = 1;
	f1 = new TF1("f1", "[0] * sin(x)", 0, 10);
	f1->SetParameter(0, k);
	f2 = new TF1("f1", "[0] * cos(x)", 0, 10);
	f2->SetParameter(0, k);
	sprintf(strb, "%s_%d", "canva", k);
	c = new TCanvas(strb, strb);
	p1 = new TPad("p1", "p1", 0.01, 0.01, 0.49, 0.99);
	p2 = new TPad("p2", "p2", 0.51, 0.01, 0.99, 0.99);
	p1->SetNumber(1);
	p2->SetNumber(2);
	p1->SetFrameFillColor(30);
	p2->SetFrameFillColor(29);
	p1->Draw();
	p2->Draw();
	c->cd(1);
	f1->DrawCopy();
	delete f1;
	c->cd(2);
	f2->DrawCopy();
	delete f2;

	list = p1->GetListOfPrimitives();
	{
		TIter next(list);
		TObject *obj;

		while ( (obj = next()) ) {
			sprintf(strb, "%s", obj->GetName());
			printf("primitive name: %s\n", strb);
		}
	}
	p1->Paint();
	c->Update();
	getchar();
	return (0);
}

Also, why if I do “p1->Update” instead of “c->Update()”, p2 painted too?
Summarizing: I want too see on my screen the pad with the primitives when I want, but not after finishing the execution of a script.

Best regards,
Nazar

The Paint method Paint() of any primitive a not meant to be used by users’. programs except in some special cases. I your case I would suggest you replace:

   p1->Paint();
   c->Update();
   getchar();

by:

   c->Modifed();
   c->Update();
   getchar();

Thanks for answer, but I don’t see anything on my screen using c->Modified().

Indeed I do not really understand why you want to block your macro execution with this getchar(). The following macro works fine for me and you get the attached plot.

void canvas()
{
   TCanvas *c;
   TPad *p1, *p2;
   TList *list;
   TF1 *f1, *f2;
   int k;
   char strb[32];

   k = 1;
   f1 = new TF1("f1", "[0] * sin(x)", 0, 10);
   f1->SetParameter(0, k);
   f2 = new TF1("f1", "[0] * cos(x)", 0, 10);
   f2->SetParameter(0, k);
   sprintf(strb, "%s_%d", "canva", k);
   c = new TCanvas(strb, strb);
   p1 = new TPad("p1", "p1", 0.01, 0.01, 0.49, 0.99);
   p2 = new TPad("p2", "p2", 0.51, 0.01, 0.99, 0.99);
   p1->SetNumber(1);
   p2->SetNumber(2);
   p1->SetFrameFillColor(30);
   p2->SetFrameFillColor(29);
   p1->Draw();
   p2->Draw();
   c->cd(1);
   f1->DrawCopy();
   delete f1;
   c->cd(2);
   f2->DrawCopy();
   delete f2;

   list = p1->GetListOfPrimitives();
   {
      TIter next(list);
      TObject *obj;

      while ( (obj = next()) ) {
         sprintf(strb, "%s", obj->GetName());
         printf("primitive name: %s\n", strb);
      }
   }
}

I have some database with many entries. I don’t want to call the function, that paint single entry, over and over again. So If I will have some mechanism to see an entry not finishing macro, It’s just easier to work for me.

Ok, try:

void canvas()
{
   TCanvas *c;
   TPad *p1, *p2;
   TF1 *f1, *f2;
   int k = 1;

   f1 = new TF1("f1", "[0] * sin(x)", 0, 10);
   f1->SetParameter(0, k);
   f2 = new TF1("f1", "[0] * cos(x)", 0, 10);
   f2->SetParameter(0, k);

   c = new TCanvas("c", "c");
   p1 = new TPad("p1", "p1", 0.01, 0.01, 0.49, 0.99);
   p2 = new TPad("p2", "p2", 0.51, 0.01, 0.99, 0.99);

   p1->SetFrameFillColor(30);
   p2->SetFrameFillColor(29);
   p1->Draw();
   p2->Draw();
   p1->cd(); f1->Draw();
   p2->cd(); f2->Draw();

   c->Modified();
   c->Update();
   gSystem->ProcessEvents();
   getchar();
}

It works, but not every time.) Seems like it depends on previous session in root). So, I don’t understand what is going on).

Also, I noticed, that you remove p1->SetNumber(1) and replace c->cd(1) by p1->cd(). This two approach works different?

Weird, on which machine are you working ?

It is similar but you do not really need to loop on the pads using numbers in your example. So the 2nd approach is more compact.

ubuntu 18

I tried to execute several times the macro canvas.C. It always works the same way.

Can you try this macro?

void canvas()
{
	TCanvas *canva;
	TPad *p1, *p2;
	TList *list;
	TF1 *f1, *f2;
	int k;
	char strb[32];
	char c;

	k = 1;
 L_again:
	f1 = new TF1("f1", "[0] * sin(x)", 0, 10);
	f1->SetParameter(0, k);
	f2 = new TF1("f1", "[0] * cos(x)", 0, 10);
	f2->SetParameter(0, k);

	sprintf(strb, "%s_%d", "canva", k);
	canva = new TCanvas(strb, strb);
	sprintf(strb, "%s_%d", "pad1", k);
	p1 = new TPad(strb, strb, 0.01, 0.01, 0.49, 0.99);
	sprintf(strb, "%s_%d", "pad2", k);
	p2 = new TPad(strb, strb, 0.51, 0.01, 0.99, 0.99);
	
	p1->SetFrameFillColor(30);
	p1->SetFillColor(20);
	p2->SetFrameFillColor(31);
	p2->SetFillColor(21);
	p1->Draw();
	p2->Draw();
	p1->cd();
	f1->DrawCopy();
	delete f1;
	p2->cd();
	f2->DrawCopy();
	delete f2;

	canva->Modified();
	canva->Update();
	gSystem->ProcessEvents();
	printf("enter char\n");
	c = getchar();
	getc(stdin);
	printf("char = '%c'\n", c);
	if ('q' == c)
		return;
		/* NOTREACHED */
	k++;
	goto L_again;
}

Please, try to do the next steps several times:

  1. run root.
  2. “.L canvas.cpp”
  3. canvas()
  4. enter “q” after “enter char” command
  5. “.q”

Sometimes functions are painted on pads after the 3rd step, sometimes not. Or it’s always painted after 3rd step on you machine?

Yes, it is always painted for me.

Ok, then I don’t know what to do. Maybe, I will try to build the latest version of root.

May be

thanks for trying)

Try with:
gSystem->ProcessEvents(); gSystem->ProcessEvents(); gSystem->ProcessEvents(); // aller guten Dinge sind drei

Still doesn’t work every time. It works well 4 or 5 times in a row, and then not).

Try:
gSystem->Sleep(100); gSystem->ProcessEvents(); gSystem->Sleep(100); gSystem->ProcessEvents(); gSystem->Sleep(100); gSystem->ProcessEvents();

It really helps) 10 times in a row it works).

What operating system version / compiler version are you using?