TApplication KeyPressed signal/slot problem as standalone

Hi,

I have the following problem: I would like to create a standalone application which is filtering keyboard events. At the beginning I thought this is going to easy by using the KeyPressed signal of TApplication. This actually works fine (see attached macro) as long as I am using it from within cint. However as soon as I am compiling it into a standalone application it looks as if the application has no connection to the keyboard events anymore?!? Could you please explain me what am I doing wrong, and give me a hint how to solve the problem?

Thanks a lot

Andreas
testKeyPressed.tar.gz (2.26 KB)

Hi Andreas,

Please provide the file TKeyTest.h. It is missing.

Cheers, Ilka

Sorry, tar by accident TKeyTestDict.h instead of TKeyTest.h :blush:

Now all necessary files should be in the attachement.
testKeyPressed.tar.gz (2 KB)

Hi,

In TApplication, when you create a TCanvas (or any gui), events are processed by TGClient.
You can replace TApplication theApp("App", &argc, argv); by:TRint theApp("App", &argc, argv);
Or you can use TCanvas::ProcessedEvent signal:

class TKeyTest : public TObject, public TQObject
{
  public:
    TKeyTest();
    virtual ~TKeyTest();

    virtual void Done(Int_t status=0); // *SIGNAL*
    virtual void PrintKey(Int_t); // SLOT
    virtual void HandleProcessed(Int_t,Int_t,Int_t,TObject*); // SLOT

  private:
    TCanvas   *fCanvas;
    TPaveText *fInfo;

  ClassDef(TKeyTest, 1)
};

//------------------------------------------------------------------------
TKeyTest::TKeyTest()
{
  cout << endl << "in Constructor ..." << endl;

  fCanvas = 0;
  fInfo   = 0;

  fCanvas = new TCanvas("fCanvas", "my Canvas", 900, 10, 300, 600);

  fCanvas->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
                   "TKeyTest", this, 
                   "HandleProcessed(Int_t,Int_t,Int_t,TObject*)");
  
  fInfo = new TPaveText(0.1, 0.1, 0.3, 0.2, "rb");
  fInfo->AddText("none");
  fInfo->Draw();

  fCanvas->Show();
}

[...]

//------------------------------------------------------------------------
void TKeyTest::HandleProcessed(Int_t event, Int_t x, Int_t, TObject *)
{
   TCanvas *c = (TCanvas *) gTQSender;
   if (c != fCanvas)  {
      return;
   }
   
   if (event == kKeyPress) {
      PrintKey(x);
   }
}

Hope this will help.

Cheers,
Bertrand.

Hi Bertrand,

your solution is working (thanks for the effort), though it has a flaw: it is starting a root session. For the application I do have in mind, a cint/root session is nothing I want to have running.

It must be possible to handle the keyboard anyhow since the canvas object is doing it.

I still do not understand while the simple signal/slot mechanism doesn’t work. What is
the used of a signal KeyPressed (of TApplication) if it is never emitted when in a
compiled standalone version?

Hi,

The signal is emitted when user type in the command line. If your application doesn’t catch keyboard events in the command line (as events are processed by the GUI), I don’t see how it could emit the signal…

Cheers,
Bertrand.

Hi,

how is than the TCanvas class and the TApplication class handling the keyboard? Both classes still have access to keyboard events since the event status bar shows them. Is there any simple way to catch the keyboard events (from within a standalone application without cint)?

Cheers,
Andreas

I already answer this… I gave you both solutions (cint and TCanvas).
Please take a look again at my first post, under 'Or you can use TCanvas::ProcessedEvent signal:'
It shows the code to catch mouse events in the canvas.
But you are welcome to provide an alternate solution or suggestion if none of these is sufficient :wink:

Cheers,
Bertrand.

Hi Bertrand,

thanks a lot for your input, thought, what I have in mind is somewhat
different. My main application is a script driven application which
performs some calculations, at the end it is generating a set of
canvases which are used to check the calculation output. Since this
is done a lot of times it would be very convenient to use keyboard
keys to interact with this canvases, e.g. to switch between them
(e.g. if there are 6 canvas open, lets say ‘1’ would bring canvas 1
into focus, or tab to jump to the next canvas etc.), to change the
data presented (e.g. indicate that for the canvas in focus, the
Fourier transform shall be presented etc.).

From this description you see that I rather would like to have a
global key handler (without visible cint) so that I do not have to click
first on a specifc canvas. Therefore I thought it more logical to install
an event handler on TApplication level to filter out the key events (at
least this is what I would do in a Qt application, but I would like to
use a ROOT-only approach this time). If you have an idea how this
could be managed I would very much appreciate your input.

Cheers,
Andreas