ROOT6 Adjust TGTripleHSlider range does not work as expected

I’m using the TGTripleHSlider widget to represent the range of a histogram plus setting some region of interest using the pointer of the triple slider. The histogram is filled live and at the start of the GUI the range of the histogram can be wrong and is adjusted with a rate of a few Hertz until the peak is found and the overflow and underflow bins are not filling up anymore. I’ trying to adjust the slider position and range accordingly:

fSlider.SetRange(lowerEdge * 2, upperEdge * 2);
fSlider.SetPosition(lowerEdge, upperEdge);
fSlider.SetPointerPosition(fDeltaT->GetFitCenter());

However, the slider range which is drawn on the GUI does not adjust when I change the Range of the slider, i.e. once the Position and PointerPosition move outside of the original range, they are not shown anymore on the GUI and I can’t find which method I have to call to update the GUI slider “range”. Am I missing something?

Hi,

Could you check if the $(ROOTSYS)/tutorials/gui/Slider3Demo.C is working, and if it does, could you post a running piece of code reproducing the problem you see?

Cheers, Bertrand.

Try this:

#include <unistd.h>

#include <TApplication.h>
#include <TGFrame.h>
#include <TGTripleSlider.h>
#include <TTimer.h>

class SliderShower : public TGMainFrame {
 public:
  SliderShower() : TGMainFrame(gClient->GetDefaultRoot(), 300, 50), fSlider(this, 300, kDoubleScaleBoth, 1) {
    AddFrame(&fSlider);
    SetWindowName("SliderDemo");
    MapSubwindows();
    Resize(GetDefaultSize());
    MapWindow();
  }

  void Update() {
    Float_t min, max;
    fSlider.GetPosition(min, max);
    fSlider.SetRange(fSlider.GetMinPosition() * 0.9, fSlider.GetMaxPosition() * 0.9); //set a completely new range here
    fSlider.SetPosition(min * 0.95, max * 0.95);
    fSlider.SetPointerPosition(fSlider.GetPointerPosition() * 0.9);
    usleep(500000);
  }

 private:
  TGTripleHSlider fSlider;
};

class Updater : public TTimer {
 public:
  Updater(SliderShower& pShower) : fShower(pShower) { Start(); }

  virtual Bool_t Notify() {
    fShower.Update();
    return kTRUE;
  }

 private:
  SliderShower& fShower;
};

int main(int, char* argv[]) {
  int fargc = 1;
  TApplication app("SliderDemo", &fargc, argv);

  SliderShower shower;
  Updater updater(shower);
  app.Run(kTRUE);
  return 0;
}

Hi,

OK, I see the problem. I’ll investigate.

Cheers, Bertrand.

Thank you :slight_smile:

Hi,

Your code cannot work properly. After a few iterations, the min and max values passed as argument to SetRange() are almost equal and the widget gets confused… Anyway, you could try to use this code to update the slider:

      gClient->NeedRedraw(&fSlider, kTRUE);

Cheers, Bertrand.

Thanks, the gClient tip worked like a charm. Concerning the guy being confused, that was just a quick way to reproduce the problem… I would suggest adding the redraw to the SetRange method?
Cheer
Arnim

Hi Arnim,

[quote=“ArnimBalzer”]I would suggest adding the redraw to the SetRange method?[/quote]I don’t think so. The user has the responsibility to update the widget when he decides it is the right time to do so. Let’s imagine your loop is changing the range every millisecond, then you just want to update the widget at the end of the loop.

Cheers, Bertrand.

Okay true, but mayo it’s just me but I couldn’t find the gClient->DoRedraw() method. Maybe extend the documentation then?

Right. Will update the documentation.