Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Function pointers in Qt
Forum Updated to NodeBB v4.3 + New Features

Function pointers in Qt

Scheduled Pinned Locked Moved C++ Gurus
30 Posts 7 Posters 31.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    TheDestroyer
    wrote on last edited by
    #19

    Here is the thing. setValue(...) is a member function of another class's object, where I want to call the function INSIDE that object after to set a value INSIDE that object.

    Since this operation is not specific and isn't supposed to control a single situation, or in other words one object's variable but rather apply the same slider with the spinbox to many other variables (this is the idea in the first place), I want to pass the "setValue(...)" function to the class, so that the class could use it as it needs.

    Doesn't this look difficult?

    1 Reply Last reply
    0
    • G Offline
      G Offline
      giesbert
      wrote on last edited by
      #20

      If you want to work with any type of objects, and those objects are QObject derived classes AND the value to set is a property, you could also use Qt's meta object system so set and get the property. :-) Is that elegant enough?

      Nokia Certified Qt Specialist.
      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

      1 Reply Last reply
      0
      • T Offline
        T Offline
        TheDestroyer
        wrote on last edited by
        #21

        ahhhhh, man! this is veryyyyyyyyyyyyyyyy diasppointing. The class isn't Qt derived :D

        but I think I'm starting to get the solution. but I need your help!

        I'm reading a book called "Professional C++" by Solter and Kleper.

        An example solution to my problem is the following (under Pointers to Methods):

        @
        SpreadsheetCell myCell;
        double (SpreadsheetCell::*methodPtr) () const = &SpreadsheetCell::getValue;
        cout << myCell.*methodPtr) () << endl;
        @

        I'm trying to do like this code as follows:

        @
        double (Blochsim::*getConstantFieldDirPtr) () const = &Blochsim::getConstantFieldDirection();
        @
        but this line is giving me the following error:

        cannot call member function 'double Blochsim::getConstantFieldDirection()' without an object.

        I tried to define and object from the class Blochsim (which I know doesn't make sense because it's in another line):

        @
        Blochsim bs;
        double (Blochsim::*getConstantFieldDirPtr) () const = &Blochsim::getConstantFieldDirection();
        @
        but still gives the same error!

        any idea how to solve this??? :D I'm happy I'm getting close to the solution!!!

        1 Reply Last reply
        0
        • G Offline
          G Offline
          giesbert
          wrote on last edited by
          #22

          remove the brakets :-)

          @
          double (Blochsim::*getConstantFieldDirPtr) () const = &Blochsim::getConstantFieldDirection;
          @

          But where do you get the object instance from to call the method on?

          Nokia Certified Qt Specialist.
          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

          1 Reply Last reply
          0
          • T Offline
            T Offline
            TioRoy
            wrote on last edited by
            #23

            It would be:

            @
            (bs.*getConstantFieldDirPtr)();
            @

            Example:
            @
            class TObj {
            public:
            double funcA() {
            return 0;
            }

            };

            int main(int argc, char *argv[])
            {
            TObj tobj;

            double (TObj::*funcAPtr)() = &TObj::funcA;
            
            (tobj.*funcAPtr)();
            

            }
            @

            I've write some years an similar code on PalmOS.

            1 Reply Last reply
            0
            • G Offline
              G Offline
              giesbert
              wrote on last edited by
              #24

              But then again, you need the object where you call it. If I understood correctly, he does not want to have the object in present. otherwise, he would not need that.

              I would go with "boost::bind":http://www.boost.org/doc/libs/1_46_1/libs/bind/bind.html#with_boost_function

              Nokia Certified Qt Specialist.
              Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

              1 Reply Last reply
              0
              • T Offline
                T Offline
                TioRoy
                wrote on last edited by
                #25

                I agree.

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  giesbert
                  wrote on last edited by
                  #26

                  So, I have a working example for your needs together with boost::bind and boost::function.
                  here we go:

                  @
                  #include <QtGui/QWidget>
                  #include <boost/function.hpp>

                  class MyWidget : public QWidget
                  {
                  Q_OBJECT
                  public:
                  explicit MyWidget(QWidget *parent = 0);

                  protected slots:
                  void changed1(int);
                  void changed2(int);

                  private:
                  boost::function<void(int)> setValue1;
                  boost::function<void(int)> setValue2;
                  };
                  @

                  I have a widget with two children, a slider and a spin box. The change of one of the triggers the slots. There I will (without using the class) change the value of the other object:

                  @
                  #include <QtGui/QSlider>
                  #include <QtGui/QSpinBox>
                  #include <QtGui/QVBoxLayout>
                  #include <boost/bind/bind.hpp>

                  MyWidget::MyWidget(QWidget parent) :
                  QWidget(parent)
                  {
                  QSlider
                  pSlider = new QSlider(Qt::Horizontal, this);
                  pSlider->setRange(0,100);
                  pSlider->setValue(20);
                  connect(pSlider, SIGNAL(valueChanged(int)), this, SLOT(changed1(int)));

                  QSpinBox* pSpin = new QSpinBox(this);
                  pSpin->setRange(0,100);
                  pSpin->setValue(20);
                  connect(pSpin, SIGNAL(valueChanged(int)), this, SLOT(changed2(int)));
                  
                  QVBoxLayout* pLayout = new QVBoxLayout(this);
                  pLayout->addWidget(pSlider);
                  pLayout->addWidget(pSpin);
                  setLayout(pLayout);
                  setFixedSize(sizeHint());
                  
                  setValue1 = boost::bind(&QSlider::setValue, pSlider, _1);
                  setValue2 = boost::bind(&QSpinBox::setValue, pSpin, _1);
                  

                  }

                  void MyWidget::changed1(int value)
                  {
                  setValue2(value);
                  }

                  void MyWidget::changed2(int value)
                  {
                  setValue1(value);
                  }
                  @

                  the trick here is the usage of

                  • boost::function<void(int)> setValue1;
                    together with:
                  • setValue1 = boost::bind(&QSlider::setValue, pSlider, _1);

                  The only disadvantage is: you need boost (at least partially...)

                  you need (at least on boost 1.44) all headers in boost, and the following folders in boost:

                  • bind
                  • config
                  • detail
                  • exception
                  • function
                  • function_types
                  • mpl
                  • preprocessor
                  • type_traits
                  • utility

                  Nokia Certified Qt Specialist.
                  Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                  1 Reply Last reply
                  0
                  • T Offline
                    T Offline
                    TheDestroyer
                    wrote on last edited by
                    #27

                    I have the object under the following hierarchy, which is in another window!

                    ((MainWindow*)parentWidget())->openGLApp->blochsim->setConstantFieldDirection(double value)

                    I'll give it a shot and try!! thank you all!

                    do you see it a problem anyway calling the object like that? I have access to the object that way!!

                    1 Reply Last reply
                    0
                    • G Offline
                      G Offline
                      giesbert
                      wrote on last edited by
                      #28

                      it is the same logic:

                      @
                      boost::function<void(double)> setValue1;

                      setValue1 = boost::bind(&CBlochism::setConstantFieldDirection, ((MainWindow*)parentWidget())->openGLApp->blochsim, _1);
                      

                      @

                      make the boost::function the parameter, like here:

                      @
                      LinkedSliderDoubleSpinBox::LinkedSliderDoubleSpinBox(double minValue, double maxValue, long int bins,
                      boost::function<void(double)>,
                      boost::function<double()>, QWidget *parent) :
                      QWidget(parent)
                      {...}
                      @

                      and call it like this;

                      @
                      boost::function<void(double)> setValue = boost::bind(&CBlochism::setConstantFieldDirection,
                      ((MainWindow*)parentWidget())->openGLApp->blochsim, _1);
                      boost::function<double()> getValue = boost::bind(&CBlochism::getConstantFieldDirection,
                      ((MainWindow*)parentWidget())->openGLApp->blochsim, _1);

                      constantFieldDirChanger = new LinkedSliderDoubleSpinBox(minConstantDir, maxConstantDir, sliderLength, 
                                                                              setValue, getValue, this);
                      

                      @

                      EDIT: updated the examples, Gerolf

                      Nokia Certified Qt Specialist.
                      Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                      1 Reply Last reply
                      0
                      • T Offline
                        T Offline
                        TheDestroyer
                        wrote on last edited by
                        #29

                        Thanks! I'll tell you what I get as soon as it's tested!

                        Unfortunately, I'll have to go get some sleep now because I'm traveling tomorrow early to Berlin... so I'll try everything I can in the train :D

                        Good night everyone, and thanks for the help!

                        see you tomorrow, with success hopefully :-)

                        1 Reply Last reply
                        0
                        • G Offline
                          G Offline
                          giesbert
                          wrote on last edited by
                          #30

                          Good night :-)
                          Please regard the updates I made to the code

                          Nokia Certified Qt Specialist.
                          Programming Is Like Sex: One mistake and you have to support it for the rest of your life. (Michael Sinz)

                          1 Reply Last reply
                          0

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved