Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Why does calling setValue in my Customer Slider Class cause the program to crash?



  • Kind of a follow up from my last post. However not related in context (at least I don't think they are).

    This is going to seem a little silly but please follow me if you can:

    class Slider : public QSlider
    {
        Q_OBJECT
    public:
        Slider(QWidget *parent = nullptr);
    
        void updateValue(int value) { setValue(value);}
        int get() const { return value(); }
    };
    

    Simply put, I am just trying to update the value of the custom slider via a controller (I know, I can do this with slots by doing ui->horizontalSlider->setValue(int);).

    I have a Controller<T....> controller(t&...), which takes an arbitrary number of Classes and allows me to set their values and get their values, for example:

    Controller<CustomSlider,CustomSpinBox,MyClass> controller(*ui->horizontalSlider,*ui->spinBox,myClass);
    

    So what I do with the slot, is tell the controller to update all of the values like so:

    void MainWindow::on_horizontalSlider_valueChanged(int value)
    {
        controller.setValues(value);
        getValues();
    }
    

    getValues() simply outputs to the console to tell me that they have indeed all updated.

    setValues(int) calls the function updateValue(int) which calls each classes setter function. It should be a straight forward update, however whenever I try to move the slider the program crashes and the debugger doesn't really give me anything useful other than crashing on qabstractslider.cpp line 531 Q_D(QAbstractSlider). So I don't really know what is going on with this. Does anyone have any suggestions?

    EDIT: Forgot to mention that ui->horizontalSlider has been promoted to Slider.

    EDIT 2: Here is the header file I have been using:

    #ifndef CONTROLLER_HPP
    #define CONTROLLER_HPP
    
    #include <functional>
    #include <vector>
    #include <iostream>
    #include <utility>
    
    template<typename...Classes>
    class Controller
    {
      public:
        Controller(Classes&...objects) : objects(objects...){}
        Controller(std::tuple<Classes&...> tup) : objects(tup){}
    
        void setValues(int value)
        {
          std::apply([&](auto&...x) { (x.updateValue(value),...);}, objects);
        }
    
        void getValues(std::vector<int> &values) const
        {
          std::apply([&](auto&...x) { (values.push_back(x.get()),...);}, objects);
        }
    
        std::tuple<Classes&...> getObjects() const
        {
          return objects;
        }
    
      private:
        std::tuple<Classes&...> objects;
    };
    
    template<typename...ClassesL, typename...ClassesR>
    auto operator+(const Controller<ClassesL...>& lhs, const Controller<ClassesR...>& rhs)
    {
      return Controller(std::tuple_cat(lhs.getObjects(),rhs.getObjects()));
    }
    
    template<typename...ClassesL, typename ClassesR>
    auto operator+(const Controller<ClassesL...> &lhs, ClassesR rhs)
    {
      Controller<ClassesR> makeController(rhs);
      return Controller(std::tuple_cat(lhs.getObjects(),makeController.getObjects()));
    }
    
    template<typename ClassesL, typename...ClassesR>
    auto operator+(ClassesL lhs, const Controller<ClassesR...> &rhs)
    {
      Controller<ClassesL> makeController(lhs);
      return Controller(std::tuple_cat(makeController.getObjects(),rhs.getObjects()));
    }
    
    #endif // CONTROLLER_HPP
    


  • @Sailanarmo

    What exactly IS in line 531?

    You said updateValue from your custom slider will call the setValue from QSlider, but in your code you call setValue(value) directly...

    Passing *ui->slider looks wrong too. AFAIK are ui-elements already pointers to the object.



  • @Pl45m4 Line 531 is what I posted Q_D(QAbstractSlider), that is line 531 in qabstractslider.cpp.

    Am I not supposed to call setValue(value) directly? This has no problem running if I do:

    Slider mySlider;
    SpinBox mySpinBox;
    MyClass myClass;
    
    controller(mySlider,mySpinBox,myClass);
    controller.setValues(20);
    

    However, mySlider and mySpinBox are not ui->horizontalSlider or ui->spinBox. But the calls should be the same right?


  • Lifetime Qt Champion

    @Sailanarmo run your program in a debugger and on crash, inspect the stack trace. you're likely accessing an invalid pointer.



  • @aha_1980 If I am accessing an invalid pointer, where would be the best place to fix it? I'll edit the post and show the controller header file.


  • Lifetime Qt Champion

    @Sailanarmo said in Why does calling setValue in my Customer Slider Class cause the program to crash?:

    where would be the best place to fix it

    Of course at the place where you create the crash.

    As said, inspect the backtrace. Everything else is guessing.


Log in to reply