I’ve tried to reduce this to a simple problem, but it is very odd. I will try to explain what I am doing to see if anyone can provide insights.
I have created a window composed of a TGMainFrame. Inside this I have a menu and a Canvas that I fill with a DrawFrame and that’s about it. I have hooked up a ProcessedEvent method to the class to capture the mouse button clicks in the canvas.
Separately I have a dialog that I wish to capture mouse coordinates in. I have made a signal that is emitted when the kButton1Down calls. This updates the
information in the Dialog.
The problem is that when this signal is received, the TGNumberEntry pointers in the dialog are corrupted. (Smells like a memory overwrite). I’ve tried a number
of different things to isolate the problem, but I can’t seem figure out what is the main cause of the corruption.
Any suggestions? I have attached the code if anyone has the fortitude to read it.
The test code has morphed a bit, and exhibits the symptoms even sooner. It is very curious. In this test code, the private data in the dialog is corrupted after the signal is emitted.
Chris testme.tar.gz (11.5 KB)
You have to diconnect the signals from the canvas to the dialog when closing the dialog. E.g.:NodeDlg::~NodeDlg()
{
TCanvas *c1 = fFHWindow->GetEmbeddedCanvas()->GetCanvas();
Disconnect(c1, "ProcessedEvent(Int_t, Int_t, Int_t, TObject *)", this, "ProcessedEvent(Int_t, Int_t, Int_t, TObject *)");
}
Otherwise the dialog will stay in the list of receivers…
And note also there are several errors in your code, e.g. this kind of connection:
fMain->Connect("CloseWindow()", "NodeDlg", fMain, "CloseWindow()");
[...]
tb->Connect("Clicked()", "NodeDlg", fMain, "DoOK()");
should be:
fMain->Connect("CloseWindow()", "NodeDlg", this, "CloseWindow()");
[...]
tb->Connect("Clicked()", "NodeDlg", this, "DoOK()");
As you see, you try to connect a class “NodeDlg” but you pass a pointer to a TGTransientFrame… (just check, all signals are wrong - like these two)
Making these modification, your code seems to work (note I tested on Windows only).
Could you try and let me know, please?
I don’t have access to fFHWindow in NodeDialog. Did you add it into the class
definition in your copy and equate it in the constructor?
Thanks for pointing out the way I was misusing the Connect! I think that was part of my misunderstanding. I also misunderstood something I read. I hope you can help on this.
Previously, I had NodeDlg as a class of TGTransientFrame. I changed things to see if the behavior changed. In the case where NodeDlg is part of TGTransientFrame ( class NodeDlg : public TGTransientFrame) is it true that signals will automatically disconnect? I thought that they would based on the statement in the documentation under TQObject
" If receiver is class not derived from TQObject and going to be
deleted, disconnect all connections to this receiver.
In case of class derived from TQObject it is done automatically."
I was pretty sure that deleting the TGTransientFrame would fall into the last statement. Am I wrong?
I’ll be trying the code today and I will report back. Thank you so much for your help.
Implementing it this way: class NodeDlg : public TGTransientFrame is obviously the best way to do it (in my point of view).
And yes, in TQObject destructor, the signals and connections should be unreferenced (disconnected)…
And obviously, I had to implement the getter in FHWindow:class FHWindow : public TGMainFrame {
public:
TRootEmbeddedCanvas *GetEmbeddedCanvas() const { return fEmbeddedCanvas; }
And a member pointer to the original fFHWindow in NodeDialog:
class NodeDlg : public TQObject // public TGTransientFrame would be better
{
private:
FHWindow *fFHWindow;[/code]
And assign it in the costructor:NodeDlg::NodeDlg(const TGFrame *main)
{
fFHWindow = (FHWindow *)main;
But when you have this kind of problem, just try to disconnect signals before the destruction of the (TQObject) slot itself.
Still having problems. I’ve made the changes you suggested and cut out some more extraneous code. I’m wondering if somehow my x-server is the problem. I’m running RH FC 8 and I’ve had some problems with X applications, however nothing in root.
Just to be sure about our discussion. I do a mouse click then close the dialog.
When opening the dialog it dies on the second mouse click. You did not observe this on the windows side? Was this using cygwin or Visual c++?