TGNumberEntry and Signals

I’ve got a number of TGNumberEntry widgets in a dialog. I want to use the Signal/Slot mechanism to find out when their values change. Seems like it should be simple enough (and with only one, it is), but I can’t figure out how to do it in the framework I describe below.

When handling menu events, I do the following sort of thing:

  pConfigMenu->Connect("Activated(Int_t)", "SPMainFrame",
		       this, "ProcessMenus(Int_t)");

where the menu entries Emit “Activated(Int_t)”, where the Int_t is the menu id. I then have one public function (ProcessMenus) that is the target of all the Connects for all the menus. This dispatches to a series of private functions, keeping the interface clean. Works fine.

When handling button events, I do something similar:

  button_autonext->Connect("Clicked()", "SPMainFrame",
			   this, "ProcessButtons(=autonext_button)");

where the public ProcessButtons handles all the button events, again dispatching to private functions. In this case, I have to pass an explicit argument (autonext_button here, an enum value) to ProcessButtons in order to disambiguate the buttons … and that works fine too, with a nice, clean public interface.

Now, I get to the TGNumberEntry. It looks like I should be able to hook one of ValueChanged(Long_t) or ValueSet(Long_t) to get a value change notification. Again, I would like to write a single function DoUpdateState(Int_t). In this case the Int_t argument would disambiguate the TGNumberEntry fields. I figured the following type of thing would work:

  numenter[e_min_serial]->
    Connect("ValueSet(Long_t)",
	    "SelectorDlg", this, "DoUpdateState(=e_min_serial)");

But this doesn’t work as I was naively expecting. I get the signal at every change in value (good!), but instead of my slot seeing “e_min_serial”, I get the Long_t Emitted by TGNumberEntry::ValueSet (not good!). This of course has nothing to do with the updated value, or the unique widget ID I set in the TGNumberEntry constructor call, so I can’t tell which of my TGNumberEntry fields has signalled me. I could, of course, add a function in the public interface of the class for each and every TGNumberEntry field in the dialog, but I’m hoping that won’t be necessary, as it would make a real mess of the interface.

Any suggestions? Is there some easy and legal way to do what I’m trying to do above? Does TGNumberEntry Emit some other signal that gets me where I want to be that I’m just missing? Thanks in advance for any help you can offer me!

In case that wasn’t clear, here’s a very simplified script that shows my difficulty:

#include <iostream>
#include "RQ_OBJECT.h"

class A {
  RQ_OBJECT("A");
public:
  A(){}
  void foobar(Long_t);//*SIGNAL*
};
void A::foobar(Long_t)  {Emit("foobar(Long_t)", 1L);}

class B {
public:
  B(A* a) { a->Connect("foobar(Long_t)", "B", this, "test(=2)"); }

  void test(Int_t a) { std::cout << a << '\n'; }
};

My root session says:

root [0] .L test3.cc+
Info in <TUnixSystem::ACLiC>: creating shared library /home/krlynch/temp/root/class-signal/./test3_cc.so
root [1] A a
root [2] B b(&a)
root [3] a.foobar(1L)
1

whereas I was naively expecting “2” for output. If I eliminate all mentions of Long_t above, and take out the second argument to the Emit, the output is “2” as I expect.

Hi,
Please see:
http://root.cern.ch/phpBB2/viewtopic.php?t=4447&start=0&postdays=0&postorder=asc&highlight=signal+slot

Cheers,
Bertrand.

I’ve a similar problem and the link reported here is not working.

fEyeTextField = new TGNumberEntry(fdCuts,kEyeMin,1,eAnyFD,
                                    TGNumberFormat::kNESInteger,
                                    TGNumberFormat::kNEANonNegative);
fEyeTextField->Connect("ValueSet(Long_t)", "EventSelection", this,
					  "HandleButtonSignals()");

If I print

fEyeTextField->WidgetId()

I get the correct number (eAnyFD),
but inside the member “HandleButtonSignals()”, the id is something else

void EventSelection::HandleButtonSignals() {
  const TGButton* button = (TGButton*)gTQSender;
  const UInt_t id = button->WidgetId();

I don’t understand what is going on…

Cheers,
Alessio

Hi Alessio,

Here is the proper link:
http://root.cern.ch/phpBB3/viewtopic.php?t=4447&start=0&postdays=0&postorder=asc&highlight=signal+slot
(the other one refers to the old phpBB2)

And in your code:const TGButton* button = (TGButton*)gTQSender;
Why do you cast gTQSender to a TGButton? It is a TGNumberEntry, not a TGButton… You should try:

Cheers, Bertrand.

I see… Thanks… Stupid mistake ^^
I knew it were stupid! But I didn’t saw it…

It was and already implemented code and I needed to modify.
Thanks!

No problem, and BTW, you have to cast it to TGNumberEntry, as shown here:

Cheers, Bertrand.

Yes, I understood the logic… Thanks, you were very helpful! :slight_smile:

You’re welcome! So your problem is fixed?
Cheers, Bertrand.