How to catch keyboard input in Application?

Hello,

I want to catch keyboard input from an existing TApplication (without deriving a new class) and also when a specific TCanvas is selected (focus on it).

Is there any example how to achieve that ? I believe I am looking for a static method to connect with keyboard input, but I don’t know which one.

Thank you.
M.

Dear @meyerma ,

Thanks for reaching out to the forum! Maybe @bellenot can help you here.

Cheers,
Vincenzo

You could use for example:

myCanvas->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", "MyClass (or empty if it's a script/macro)",
               this or nullptr, "CaptureEvent(Int_t,Int_t,Int_t,TObject*)");

and then you implement void MyClass::CaptureEvent or just void CaptureEvent in a macro.

see examples within the tutorials folder:

gui/exec3.C:   c1->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", nullptr, nullptr,
gui/statusBar.C:   myc->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)","MyMainFrame",this,
gui/guitest.C:   fFrame->Connect("ProcessedEvent(Event_t*)", "TileFrame", this,
gui/guitest.C:   fEc1->GetCanvas()->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",

If you rather want to catch ctrl+C or signals like that, then use:

std::shared_ptr<TSignalHandler> interruptHandler = std::make_shared<TSignalHandler>(kSigInterrupt, kFALSE);
    interruptHandler->Add();

and you can redirect things to prevent kill with things like:


        gVirtualX->GrabKey(GetId(), gVirtualX->KeysymToKeycode(kKey_c),
                           kKeyControlMask, en); // capture CTRL+C
        gVirtualX->GrabKey(GetId(), gVirtualX->KeysymToKeycode(kKey_c),
                           kKeyControlMask | kKeyMod2Mask,
                           en); // capture CTRL+C NumLock on

Hi @ferhue

Thank you very much. I managed to catch the simple char using Connect()
Here is my test program.

class MyKeyboard
{
     public:

    ~MyKeyboard() {}
     MyKeyboard() {}
     MyKeyboard(TCanvas *myCanvas)
     {
        myCanvas->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)", "MyKeyboard", this, "CaptureEvent(Int_t,Int_t,Int_t,TObject*)");
        myCanvas->SetTitle(myCanvas->GetTitle() + TString(" [Keyboard]"));
     }

     void CaptureEvent(Int_t event, Int_t x, Int_t y, TObject *obj)
     {
        if (event == kKeyPress)
             std::cout << "Capture Event for " << obj << " (" << event << "; char = " << ((char) x) << ";" << ((char) y) << ")" << std::endl;
     }
};

void Canvas() {

        TCanvas *c1 = new TCanvas("c1", "First canvas", 510, 0, 500, 500);
        TH1F *h1 = new TH1F("h1", "h1", 100,-10,10);
              h1->FillRandom("gaus", 1000);
              h1->Draw();

        TCanvas *c2 = new TCanvas("c2", "Second canvas", 0,0, 500, 500);
        TH1F *h2 = new TH1F("h2", "h2", 100,-10,10);
              h2->FillRandom("pol2", 1000);
              h2->Draw();

        MyKeyboard *keyboard = new MyKeyboard(c1);
}

However, it doesn’t seems to catch arrow keys.

My goal is more to extend my reading of input(stdin) using getchar() to TCanvas (or any root graphics). I basically want just to intercept any key touch including the special ones.

The arrow keys are automatically catched by ROOT in a Canvas to move instead the cursor by one pixel.
So you can “detect” arrow keypress by checking if previous and current position just differs by one pixel. (px,py)

1 Like

Looks like a good idea, thank you so much! I just tested and I can indeed catch left/right/top/bottom that way. I will try to inject into stdin to see if this can be processed using getchar()

Any idea how to catch shift and ctrl ? I am sorry I couldn’t get gVirtualX::GrabKey I dont know what GetID() and en are. Could you let me know on that part too ?

See here some examples

The full options are:



// Key masks, used as modifiers to GrabButton and GrabKey and
// in Event_t::fState in various key-, mouse-, and button-related events
const Mask_t kKeyShiftMask   = BIT(0);
const Mask_t kKeyLockMask    = BIT(1);
const Mask_t kKeyControlMask = BIT(2);
const Mask_t kKeyMod1Mask    = BIT(3);   ///< typically the Alt key
const Mask_t kKeyMod2Mask    = BIT(4);   ///< typically mod on numeric keys
const Mask_t kKeyMod3Mask    = BIT(5);
const Mask_t kKeyMod4Mask    = BIT(6);
const Mask_t kKeyMod5Mask    = BIT(7);
const Mask_t kButton1Mask    = BIT(8);
const Mask_t kButton2Mask    = BIT(9);
const Mask_t kButton3Mask    = BIT(10);
const Mask_t kButton4Mask    = BIT(11);
const Mask_t kButton5Mask    = BIT(12);
const Mask_t kButton6Mask    = BIT(13);
const Mask_t kButton7Mask    = BIT(14);
const Mask_t kAnyModifier    = BIT(15);
1 Like

en(able) is a boolean, true to activate the shortcut, false to deactivate it.

GetId() is the Handle_t id of the window. For example, if you have a custom class inheriting from TGMainFrame, GetId() will exist. Not sure if you just a proper canvas, if there’s a way to get it’s parent Id. Maybe just setting 0 or 1 works?. @couet might help here.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.