Disable Mouse Clicks in a TCanvas/TPad

Hi.

I have a program that displays histograms as it receives data. I’d like to disable my TCanvas from receiving mouse clicks so that the use can’t muck around with the display. Yet, I still want the ability of the program to draw inside of the canvas. Using TPad::SetEditable(false) does more than I want - it disables the mouse, but also disables the ability to add objects and draw.

How can I accomplish my task?

Thanks,
Adam

Hi,

Sorry, but I think there is no solution…

Cheers, Bertrand.

Use TPad::SetEditable(kFALSE) , then instead of object->Draw(option), do

mypad->GetListOfPrimitives()->Add(object,option);
Rene

Dear Rooters,
According to the question expressed in this subject, i would like to get informed whether it is possible to DISABLE the move of a drawn histogram inside the TPad or TCanvas when you click and drag the mouse over the drawn histo/graph. This can be achieved with SetEditable but, as it was mentioned, this option also forbids many more things that i need.

What i need is not to forbid in general the clicking over the histo/graph but when i left click to not be allowed the graph/histo to be moved inside the Tpad/Tcanvas.

thanks
regards!

That’s what TPad::SetEditable is supposed to do. Did you really try?

Rene

Sorry, apparently i did not describe in details what i was meant.
Yes i 've tried it. But the problem is the following:
This pad is used into a stand alone GUI application where the users can plot/load several histos of their choice. If a histo is drawn on the embedded Canvas and i set the SetEditable(kFALSE) option, using the right click menu on the pad for example, of course the histo/graphs are not moving anymore with the mouse but i realized that then I can not also add another histo into the same pad. Furthermore the zoom property using the mouse across each axis do not work as well… So from this experience i conclude that SetEditable does not only restricts the motion of the graph but other options that i really need.
Is there any way to restrict only the histo movement or lock its position and without restricting anything else?

thanks

Any ideas?

D.

I strongly oppose to tweaking such basic things as histogram package needlessly.

Bugs are always showing up.

Here is what people do in your case:

every time user wants to plot a histogram your program
should make a temporary copy and draw copy instead. User may do whatever he/she wants all the way to even deleting it.
Original is still intact.
And you can always add bells and whistles like “refresh” button, or making copy from original from time to time and redisplaying the copy…
This is not hard to code up without messing up ROOT intestines :slight_smile:.

[quote=“gadamcm”]… I’d like to disable my TCanvas from receiving mouse clicks so that the use can’t muck around with the display. Yet, I still want the ability of the program to draw inside of the canvas. Using TPad::SetEditable(false) does more than I want - it disables the mouse, but also disables the ability to add objects and draw.

How can I accomplish my task?
[/quote]Do you want to create some sort of pixmap image of your histogram and then use that pixmap as TCanvas background? The TCanvas background doesn’t respond to mouse event. On the other hand one can keep populating the TCanvas with the other “real” objects via “TObject::Draw” method. These objects are to be rendered over the TCanvas background and are to respond to the mouse movement as needed.

If the only thing that you want to do is preventing to move the frame inside the pad/canvas, you can do

   mypad->GetFrame()->SetBit(TBox::kCannotMove);

Rene

Thank you all for your valuable replies.

[quote=“brun”]If the only thing that you want to do is preventing to move the frame inside the pad/canvas, you can do

Rene[/quote]

Rene, the method you indicate is exactly what i was looking for. It works great now! Thanks again.

regards.

I couldn’t make this work for divided canvases and embedded Canvas.
any hints?

Hi,

This works for me…

// example_slot.C
#include <TCanvas.h>
#include <TF1.h>
#include <TRandom.h>
#include <TGButton.h>
#include <TGFrame.h>
#include <TRootEmbeddedCanvas.h>

class MyMainFrame : public TGMainFrame {
private:
   TRootEmbeddedCanvas *fEcanvas;
public:
   MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h);
   virtual ~MyMainFrame();
   void DoDraw();
};
 
MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) : 
   TGMainFrame(p, w, h)
{
   // Create canvas widget
   fEcanvas = new TRootEmbeddedCanvas("Ecanvas", this, 200, 200);
   AddFrame(fEcanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY,
            10, 10, 10, 1));
 
   // Create a horizontal frame widget with buttons
   TGHorizontalFrame *hframe = new TGHorizontalFrame(this, 200, 40);
   TGTextButton *draw = new TGTextButton(hframe, "&Draw");
   draw->Connect("Clicked()", "MyMainFrame", this, "DoDraw()");
   hframe->AddFrame(draw, new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4));
   TGTextButton *exit = new TGTextButton(hframe,"&Exit","gApplication->Terminate(0)");
   hframe->AddFrame(exit, new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4));
   AddFrame(hframe, new TGLayoutHints(kLHintsCenterX, 2, 2, 2, 2));
 
   // Set a name to the main frame
   SetWindowName("Simple Example");
   // Map all subwindows of main frame
   MapSubwindows();
   // Initialize the layout algorithm
   Resize(GetDefaultSize());
   // Map main frame
   MapWindow();
}
 
void MyMainFrame::DoDraw()
{
   // Draws function graphics in randomly choosen interval
   TCanvas *fCanvas = fEcanvas->GetCanvas();
   fCanvas->cd();
   fCanvas->SetEditable(kTRUE);
   TF1 *f1 = new TF1("f1", "sin(x)/x", 0, gRandom->Rndm()*10);
   f1->SetFillColor(19);
   f1->SetFillStyle(1);
   f1->SetLineWidth(3);
   f1->Draw();
   fCanvas->SetEditable(kFALSE);
   fCanvas->Update();
}
 
MyMainFrame::~MyMainFrame()
{
   // Clean up used widgets: frames, buttons, layouthints
   Cleanup();
}
 
void example_slot()
{
   // Popup the GUI...
   new MyMainFrame(gClient->GetRoot(),200,200);
}

Cheers, Bertrand.

I the post from Rene (Feb '09) the code seems to be missing.
Does any one know what was there? I would like to apply this solution.

Regards,
Andrey

I edited the post, the code is:

mypad->GetFrame()->SetBit(TBox::kCannotMove);

Thanks a lot Bertrand!

1 Like