Gui do not close properly when exiting eventloop

Dear Rooters,

I have a problem when I try to exit the event loop in stand alone program with GUI:
when I want to exit the gui (e.g. with gSystem->ExitLoop() ) and continue to do something the GUI do not vanish and is somehow frozen.
I am running my code on Mac OS mavericks and using ROOT 5.34/17.

Below is an example of my problem using a slightly modified tutorial found here:
root.cern.ch/root/html534/tutori … bel.C.html

I have just modified the exit button c.f. DoExit() function member.
Does somebody have any idea on what am I doing wrong?

Thanks in advance for your reply!

gui header:

//MyMainFrame.h
#ifndef MYMAINFRAME_H
#define	MYMAINFRAME_H

#include <TGClient.h>
#include <TGButton.h>
#include <TGFrame.h>

#include "TROOT.h"
#include "TApplication.h"
#include "TSystem.h"
#include <stdlib.h>
#include <string>
#include <iostream>

class MyMainFrame : public TGMainFrame
{
public:
    MyMainFrame();    
    MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h);
    virtual ~MyMainFrame();
    // slots
    void ChangeStartLabel();
    void ChangePauseLabel();
    void DoExit();
private:
    TGCompositeFrame *fCframe;
    TGTextButton     *fStart, *fPause, *fExit;
    Bool_t            start, pause;
   

   ClassDef(MyMainFrame, 0);
    
};

#endif	/* MYMAINFRAME_H */

// gui code:

//MyMainFrame.cxx
#include "MyMainFrame.h"

MyMainFrame::MyMainFrame() 
{
    
}

MyMainFrame::MyMainFrame(const TGWindow *p, UInt_t w, UInt_t h) :
TGMainFrame(p, w, h)
{
    // Create a horizontal frame containing buttons
    fCframe = new TGCompositeFrame(this, 170, 20, kHorizontalFrame|kFixedWidth);

    fStart = new TGTextButton(fCframe, "&Start");
    fStart->Connect("Clicked()", "MyMainFrame", this, "ChangeStartLabel()");
    fCframe->AddFrame(fStart, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 
                                                3, 2, 2, 2));
    fStart->SetToolTipText("Click to toggle the button label (Start/Stop)");
    start = kFALSE;

    fPause = new TGTextButton(fCframe, "&Pause");
    fPause->Connect("Clicked()", "MyMainFrame", this, "ChangePauseLabel()");
    fPause->SetToolTipText("Click to toggle the button label (Pause/Resume)");
    fCframe->AddFrame(fPause, new TGLayoutHints(kLHintsTop | kLHintsExpandX,
                                                3, 2, 2, 2));
    pause = kFALSE;

    AddFrame(fCframe, new TGLayoutHints(kLHintsCenterX, 2, 2, 5, 1));

    fExit = new TGTextButton(this, "&Exit ");
    fExit->Connect("Clicked()" , "MyMainFrame", this, "DoExit()");
    
    AddFrame(fExit, new TGLayoutHints(kLHintsTop | kLHintsExpandX,5,5,2,2));

    SetWindowName("Change Labels");

    MapSubwindows();
    Resize(GetDefaultSize());
    MapWindow();
}



MyMainFrame::~MyMainFrame() 
{
    // Clean up all widgets, frames and layouthints that were used
    fCframe->Cleanup();
    Cleanup();
}




void MyMainFrame::DoExit()
{
    CloseWindow();
    gSystem->ExitLoop();//if commented windows close properly but I am stack in the event loop
}

void MyMainFrame::ChangeStartLabel()
{
  // Slot connected to the Clicked() signal. 
  // It will toggle labels "Start" and "Stop".
  
  fStart->SetState(kButtonDown);
  if (!start) {
     fStart->SetText("&Stop");
     start = kTRUE;
  } else {
     fStart->SetText("&Start");
     start = kFALSE;
  }
  fStart->SetState(kButtonUp);
}

void MyMainFrame::ChangePauseLabel()
{
  // Slot connected to the Clicked() signal. 
  // It will toggle labels "Resume" and "Pause".
  
  fPause->SetState(kButtonDown);
  if (!pause) 
  {
     fPause->SetText("&Resume");
     pause = kTRUE;
  } else 
  {
     fPause->SetText("&Pause");
     pause = kFALSE;
  }
  fPause->SetState(kButtonUp);
}

ClassImp(MyMainFrame)

The main program:

//main.cxx
#include <iostream>
#include <csignal>
#include "MyMainFrame.h"
#include "TApplication.h"


void buttonChangelabel()
{
   // Popup the GUI...
   new MyMainFrame(gClient->GetRoot(), 500, 500);
}


int main(int argc, char** argv) 
{

    TApplication app("App", &argc, argv);
    buttonChangelabel();
    
    app.Run();
    bool run=true;
    std::cout<<"Entering infinite loop"<<std::endl;
    while(run)
    {
        run=true;//do something but gui remains
        
    }
    
    
    return 0;
}

Well, I don’t really understand what you’re trying to do, but you can simply add gSystem->ProcessEvents(); in your infinite loop:

while(run) { gSystem->ProcessEvents(); run = true;//do something but gui remains } By definition, the event processing loop is needed by the GUI…

Cheers, Bertrand.

thanks for your reply. What I wanted to do is to exit the gui and do something else after.

You could maybe try to use:
app.Run(kTRUE); // return here using “any canvas main menu” -> “File” -> "Quit ROOT"
and then in your “infinite loop”, call “gSystem->ProcessEvents();” in regular intervals.
See also: Render the canvas while a script is still executing