Step size for TGNumberEntry

Hello,

Is it possible to set arbitrary step size in TGNumberEntry? For example 5 in case of an entry containing ints? I know I can increase the number myself when the buttons are clicked, but then increasing it again sends a signal and it is easy to get into an infinite loop.

If you didn’t find a way in the TGNumberEntry class documentation, then I’m afraid there is no such option…

Cheers, Bertrand.

A shame. OK, I will try to do it manually somehow avoiding the infinite loop.

Sorry, but I don’t see where and how you can have an infinite loop… Can you post a short running macro showing the problem?

Cheers, Bertrand.

I was reacting to the Textchanged() signal. If one changes text on this signal, it goes into infinite loop :slight_smile: I assume I will have to connect separately to the signal from the buttons.

So you were changing the text when receiving the notification that the text has been changed? In this case yes, this was not a very good idea… :wink:

Well, that was just a quick test when I could not find any step setting for the control. I more or less expected the behaviour.

Btw. it would be nice to have a control being a mix between TGNumberEntry and TGList - a TGNumberEntry just going through the element of list, whatever they are. I understand that would be a very low priority feature request :slight_smile:

I think I don’t see an elegant way of doing what I want to do. Basically, I want TGNumberEntry to react differently when buttons are pressed and when the number is filled from the keyboard. However, the TGNumberEntry buttons do not send any signals…

So is there any way to tell, what type of interaction user had with the TGNumberEntry? ValueSet() signal does not seem to carry that information.

Signals from TGNumberEntry:

virtual void ValueChanged(Long_t val); //*SIGNAL* virtual void ValueSet(Long_t val); //*SIGNAL*
Signals from TGTextEntry (accessible via TGNumberEntry::GetNumberEntry()):

virtual void TextChanged(const char *text = 0); //*SIGNAL* virtual void ReturnPressed(); //*SIGNAL*
Signals from TGButton (accessible via TGNumberEntry::GetButtonUp() and TGNumberEntry::GetButtonDown()):

virtual void Pressed() { Emit("Pressed()"); } // *SIGNAL* virtual void Released() { Emit("Released()"); } // *SIGNAL* virtual void Clicked() { Emit("Clicked()"); } // *SIGNAL*
Cheers, Bertrand.

Well, it does not work for the buttons - no signal. I found on this forum, that they are not really TGButtons but TGRapidFireButton (or something like that) that do not emit signal.

Anyway, I attach modified tutorial example with connection made directly to the button.
numberEntry.C (2.84 KB)

OK, then [quote=“LeWhoo”]Well, it does not work for the buttons - no signal. I found on this forum, that they are not really TGButtons but TGRapidFireButton (or something like that) that do not emit signal. [/quote]You’re right… Anyway, you can still connect to the TGNumberEntry and the TGTextEntry signals, like for example:

fNumber->Connect("ValueSet(Long_t)", "MyMainFrame", this, "DoSetlabel(=0)"); fNumber->GetNumberEntry()->Connect("ReturnPressed()", "MyMainFrame", this, "DoSetlabel(=1)"); [...] void MyMainFrame::DoSetlabel(Int_t which) { if (which == 0) cout << "From ValueSet() signal" << endl; else if (which == 1) cout << "From ReturnPressed() signal" << endl;
Or:

fNumber->Connect("ValueSet(Long_t)", "MyMainFrame", this, "DoSetlabel()"); fNumber->GetNumberEntry()->Connect("ReturnPressed()", "MyMainFrame", this, "DoSetlabel()"); [...] void MyMainFrame::DoSetlabel() { TObject *sender = (TObject *)gTQSender; if (sender && sender->InheritsFrom("TGNumberEntry")) cout << "From ValueSet() signal" << endl; else if (sender && sender->InheritsFrom("TGTextEntry")) cout << "From ReturnPressed() signal" << endl; Or use two different slots…

Cheers, Bertrand.

ReturnPressed() still causes ValueSet() to be send later, so I need to set some flag in ReturnPressed() to know in later ValueSet that this is the case of return pressed not the button clicking :slight_smile: A little bit dirty, but if nothing else works.

Anyway, I am trying to use it from pyROOT (which makes, at this stage, this forum not fitted for this post) where I have to bind gTQSender to some object before using it. Binding to TGButton or TGNumberEntry makes of course no sense, because it imposes inheritance. I try to bind to TObject, but it also seems to destroy inheritance. I wonder if there is a way I could do this.

Btw. we have functions returning TGButton * which are actually not real TGButtons. Isn’t it a bug?

It seems that ReturnPressed() is emitted after ValueSet(). So I am afraid none of the proposed methods will work. The script will always go through ValueSet(), which does not know is there was also ReturnPressed() or not…

OK, if you want to have full control, here is the solution:

[code] fNumber->SetButtonToNum(kFALSE); //take control of the buttons

fNumber->Connect(“ValueChanged(Long_t)”, “MyMainFrame”, this, “DoSetlabel()”);
fNumber->GetNumberEntry()->Connect(“ReturnPressed()”, “MyMainFrame”, this,
“DoSetlabel()”);

[…]

void MyMainFrame::DoSetlabel()
{
TObject *sender = (TObject *)gTQSender;
if (sender && sender->InheritsFrom(“TGNumberEntry”))
cout << “From ValueChanged() signal” << endl;
if (sender && sender->InheritsFrom(“TGTextEntry”))
cout << “From ReturnPressed() signal” << endl;
[…]
[/code]
Sorry for not having noticed that before… :blush:

Cheers, Bertrand.

It worked, thanks! However it took me a while to notice that you have changed from “ValueSet” to “ValueChanged”. Still, the whole thing, together with the buttons not emitting a signal issue, calls for a documentation update someday.

I agree, or we can make the buttons emitting a signal…
Cheers, Bertrand.

I think making buttons emit the signal is the most straightforward thing. However, I am not sure if it can be done without breaking this “continuous increase” of number feature.

I suppose that’s the reason why we have this fNumber->SetButtonToNum(kFALSE); and ValueChanged(Long_t) signal. Otherwise the value would continuously change while keeping one of the buttons down, and it doesn’t make much sense to get notified only of a button state change…