matthieuguillo[quote]Hi Rooters
I am Pierre’s advisor. To clarify things a little bit, we would like to create customized graphic editors. Some are just fine and can be used as such (TPadEditor, TFrameEditor…) but other would be best replaced to fit our kind of work (TGraphEditor, TH1Editor, TH2Editor…).
What is the best way to do that? I read lka Antcheva’s presentation at ROOT2005 workshop (transparencies 13 and 14) and according to her there are a set of rules to follow but we don’t know where we can find such an example. Furthermore we are not using ROOT’s native GUI, but QT implementation from BNL (don’t ask why, this is a political decision).
Pierre thinks that we can do it another way and create our own library with objects like “MyGraphEditor”, “MyTH1Editor” and let ROOT select those instead of regular one using directives in the .rootrc. There is such an example provided by BNL .rootrc :
Plugin.TPaletteEditor: * TQtPaletteEditor QtImage "TQtPaletteEditor(TAttImage*,UInt_t,UInt_t)"
Gui.Factory: qtgui
Plugin.TGuiFactory: qtgui TQtGUIFactory QtGui "TQtGUIFactory()"
At that point we need some advise.
Thanks for your help[/quote]
Hello
I am begging pardon, I missed this post, because the Subj doesn’t attract me.
First the example you mentioned contains the typo. To provide the custom
ROOT object editor one should provide TVirtualPadEditor plugin.
For example:Plugin.TVirtualPadEditor: Ged TQtGedEditor QtGed "TQtGedEditor(TCanvas*)"
Please, can you clarify your troubles, may be in private message.
I mean the qtged suggests the solution. One can find there the “base class” all custom “editors” can be derived from. The base TQtGedAttFrame class provides the ROOT Signal / Slot Qt Signal Slot mapping".
So you shoud subclass it.
[size=42][code]class TQtArrowEditor : public TQtGedAttFrame {
#ifndef CINT
Q_OBJECT
#endif
protected:
TArrow *fModel; // arrow object
TQtArrowStyleSelect *fOptionCombo; // arrow shapes combo box
TQtFloatSpinBox *fAngleEntry; // opening angle entry
TQtFloatSpinBox *fSizeEntry; // size entry
TQtFloatSpinBox *fStartPointXEntry; // start point x entry
TQtFloatSpinBox *fEndPointXEntry; // end point x entry
TQtFloatSpinBox *fStartPointYEntry; // start point y entry
TQtFloatSpinBox *fEndPointYEntry; // end point y entry
void Ctor();
virtual void ConnectSignals2Slots();
virtual void Connect() { TQtGedAttInterface::ConnectToCanvas(fCanvas,Class
Name(), this); }
virtual void Disconnect() { TQtGedAttInterface::ConnectToCanvas(fCanvas,Class
Name(), this,kFALSE); }
public:
TQtArrowEditor(QMainWindow *mainWidget, TCanvas *canvas, Int_t id=0,
Int_t width = 140, Int_t height = 30,
UInt_t options = 0, // kChildFrame,
Pixel_t back = 0) ;
TQtArrowEditor(TCanvas *canvas, QWidget *parent=0, Int_t id=0,
Int_t width = 140, Int_t height = 30,
UInt_t options = 0, // kChildFrame,
Pixel_t back = 0) ;
virtual ~TQtArrowEditor() ;
virtual void ConnectToCanvas(TCanvas *c) { TQtGedAttInterface::ConnectToCanva
s(c,ClassName(), this); }
virtual void SetModel(TVirtualPad *pad, TObject *obj, Int_t event) ;
public slots:
virtual void DoAngle(int );
virtual void DoOption(int );
virtual void DoSize(int );
virtual void DoStartPoint();
virtual void DoEndPoint();
#ifndef Q_MOC_RUN
//MOC_SKIP_BEGIN
ClassDef(TQtArrowEditor,0) // axis editor
//MOC_SKIP_END
#endif
};[/code][/size]
May be you should send me the idea of your custom editor and I will show you how to implement it. Normally, it takes a few hours to start and complete any custom Qt-based ROOT object editor. If you do not like some particular editor you can sub-sub-class it further.
The QtGed implementation relies on the list of object editors. One can provide a public interface to edit the list instead of the protected one. class TQtGedEditor : public TVirtualPadEditor {
. . .
protected:
. . .
void Insert(Int_t indx, TQtGedAttFrame *frame);
This way one can add his/her own custom implementation to the list and remove some thing hi/she doesn’t like.
In fact, if you want to provide your own editor you should understand quite simple technique that is behind the scene and is demonstrated by the code:
void TQtGedAttInterface::ConnectToCanvas(TCanvas* c,const char *className, void *thisPointer, Bool_t connect)
{
// Connect/Disconnect the GUI attribute frames to the selected object in the canvas.
if (c) {
if (connect) {
assert(TQObject::Connect(c, "Selected(TVirtualPad*,TObject*,Int_t)", className,
thisPointer, "SetModel(TVirtualPad*,TObject*,Int_t)"));
} else {
assert(TQObject::Disconnect(c, "Selected(TVirtualPad*,TObject*,Int_t)",
thisPointer, "SetModel(TVirtualPad*,TObject*,Int_t)"));
}
}
}
Now, to force ROOT to invoke your editor you should
[ul]- Make sure the current TCanvas “Selected” ROOT signal is disconnected
[code] signals (Qt)
CanvasPainted(); // Signal the TCanvas has been painted onto the screen
Saved(bool ok); // Signal the TCanvas has been saved into the file
RootEventProcessed(TObject *selected, unsigned int event, TCanvas *c);
// Signal the Qt mouse/keyboard event has been process by ROOT
// This "signal" is emitted by the enabled mouse events only.
// See: EnableSignalEvents
// --- DisableSignalEvents[/code]QtExamples package from the BNL CVS provides a bunch of the "Hello World" examples that demonstrates the technique as well.
I am willing to provide you futher information and guidiance. Let me know