About TGMainFrame 'focus'


I have created a user interface controlled by text commands. It controls the behavior of a TGMainFrame with some sub frames. Each sub frame has a canvas - on each canvas I draw a certain graph (one is a TGraph2D, another is a TGraph, etc.). The user controls how the graphs appear by choosing commands from a menu within a controlling module and then issuing a draw command. This module, which has created the TGMainFrame object as a class member, passes the commands along to it to redraw the graphs etc.

My question has to do with how the TGMainFrame resolves when the user is allowed to click on its objects and interact with them. For example, if one draws a TGraph2D, after drawing is finished one normally has the ability to rotate the axes of the TGraph2D by clicking and dragging. However, the particular way I’ve chosen to control the drawing prevents the user from doing this until my controller module has exited its control loop, and has stopped running. Similarly, the graphs I draw to the canvases don’t ‘resize’ to fill their sub-frames until the controller stops running.

Is there a command I can issue to the TGMainFrame object to instruct it to ‘finalize’ its operations, thereby enabling the user to interact with the graphs in its canases? Or do I need to put this controlling module inside of my TGMainFrame module? (I’d rather not do this, since the controller module is a completely separate entity - only one of its functions is to instruct the TGMainFrame object how and where to draw what).

Perhaps the following pseudo-code makes this question a little more understandable. The controller creates the TGMainFrame object ‘ECF’, modifies its state according to user commands, then issues draw commands. I’ve commented where in the control flow the user can and can’t interact with the graphical frames.

MyCustomTGMainFrame* ECF = new MyCustomTGMainFrame(...);
[controller enters control loop] {
  [user chooses a command]
  [controller applies command to ECF]
  ECF->MapSubwindows();   //these three commands also work if they are in ECF's constructor instead of here, no change in behavior
  //at this point in program flow, user is not able to rotate TGraph2D and TGraph's do not fill their sub-frames
[controller repeats control loop until exit command]
//here, after the controller has exited, the user can rotate TGraph2D and TGraph's are resized properly
//however this is inconvenient because I may like to change the graph's appearance based on what I discover by rotating the TGraph2D, etc...

Thanks for your help!


In your loop call



try calling:

in your module when you need to update graphics. See also $ROOTSYS/test/stressGUI.cxx.

Cheers, Fons.

Thank you for the responses - with the gSystem->ProcessEvents() command, the TGMainFrame resizes the graphs, etc. so that they look nice, even within the control loop.

However they still aren’t clickable, for example I can’t interactively rotate the TGraph2D or choose a range on the TGraphs, until my control loop relinquishes control to the root prompt. Is there any way around this?

Thanks again,


They will only be clickable when you are out of your onw control, or when you keep calling ProcessEvent() regularly, say with a timer. But better is not to have your control at all but have you control only be called via a timer from the ROOT eventloop, this will ensure that all events are properly and timely processed. So effectively inverse the control structure you currently have.

Cheers, Fons.