Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Trouble subclassing QSlider
Qt 6.11 is out! See what's new in the release blog

Trouble subclassing QSlider

Scheduled Pinned Locked Moved General and Desktop
14 Posts 3 Posters 10.7k 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.
  • D Offline
    D Offline
    dnadave
    wrote on last edited by
    #5

    Well, just tried doing that and I still get the unresolved symbol error with vtable.

    Here's the new version of the class:

    @
    class QDSlider : public QSlider
    {
    Q_OBJECT
    public:
    explicit QDSlider():QSlider() {}
    explicit QDSlider( QWidget *parent = 0 ):QSlider( parent ) {}
    explicit QDSlider( Qt::Orientation orientation , QWidget *parent = 0 ):QSlider( orientation , parent ) {}
    signals:
    void valueChanged( double );
    private slots:
    void setValue( double );
    };
    @

    I added the file to the list of MOC_SRCS in CMake and let it do its thing. Still no go...

    This is getting pretty frustrating...

    Dave H

    1 Reply Last reply
    0
    • D Offline
      D Offline
      dnadave
      wrote on last edited by
      #6

      I was using the wrong macro in CMakelist.txt, so moc was no running. I now have that running and creating the .cxx files which do get compiled and linked. However, I am still getting an unresolved symbol error, but for the exact function moc was supposed to magically generate the definition for:

      @
      make[3]: Entering directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build' [ 7%] Generating ui_gsdesign.h [ 15%] Generating moc_gsdesign.cxx [ 23%] Generating moc_QDSlider.cxx [ 30%] Generating qrc_images.cxx Scanning dependencies of target gsdesigngui make[3]: Leaving directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build'
      make[3]: Entering directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build' [ 38%] Building CXX object CMakeFiles/gsdesigngui.dir/gsdesign.cpp.o [ 46%] Building CXX object CMakeFiles/gsdesigngui.dir/gsDesignGUI.cpp.o [ 53%] Building CXX object CMakeFiles/gsdesigngui.dir/gsDesignTips.cpp.o [ 61%] Building CXX object CMakeFiles/gsdesigngui.dir/GsRList.cpp.o [ 69%] Building CXX object CMakeFiles/gsdesigngui.dir/main.cpp.o [ 76%] Building CXX object CMakeFiles/gsdesigngui.dir/Rcpp.cpp.o [ 84%] Building CXX object CMakeFiles/gsdesigngui.dir/moc_gsdesign.cxx.o [ 92%] Building CXX object CMakeFiles/gsdesigngui.dir/moc_QDSlider.cxx.o [100%] Building CXX object CMakeFiles/gsdesigngui.dir/qrc_images.cxx.o Linking CXX shared library libgsdesigngui.so make[3]: Leaving directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build'
      [100%] Built target gsdesigngui
      make[2]: Leaving directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build' make[2]: Entering directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build'
      make[3]: Entering directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build' Linking CXX shared library CMakeFiles/CMakeRelink.dir/libgsdesigngui.so make[3]: Leaving directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build'
      make[2]: Leaving directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build' Install the project... -- Install configuration: "" -- Installing: /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/inst/libs/./libgsdesigngui.so make[1]: Leaving directory /home/david/workspace/GSDesignGUI/package/gsDesignExplorer/explorergui-build'
      ** testing if installed package can be loaded
      Error in dyn.load(file, DLLpath = DLLpath, ...) :
      unable to load shared object '/usr/local/lib64/R/library/gsDesignExplorer/libs/libgsdesigngui.so':
      /usr/local/lib64/R/library/gsDesignExplorer/libs/libgsdesigngui.so: undefined symbol: _ZN8QDSlider8setValueEd
      ERROR: loading failed

      • removing ‘/usr/local/lib64/R/library/gsDesignExplorer’
      • restoring previous ‘/usr/local/lib64/R/library/gsDesignExplorer’
        @

      Here is the unmangled symbol:

      @
      GSDesignGUI/package> c++filt _ZN8QDSlider8setValueEd
      QDSlider::setValue(double)
      @

      So, how do I get this slot and signal created?? I was told not to generate this myself, but let moc do it for me. Clearly, moc is not doing that, so how do you get it to work?!?

      Here's a copy of the class as defined in the header file moc is processing:

      @
      class QDSlider : public QSlider
      {
      Q_OBJECT
      public:
      explicit QDSlider():QSlider() {}
      explicit QDSlider( QWidget *parent = 0 ):QSlider( parent ) {}
      explicit QDSlider( Qt::Orientation orientation , QWidget *parent = 0 ):QSlider( orientation , parent ) {}
      signals:
      void valueChanged( double );
      private slots:
      void setValue( double );
      };
      @

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andre
        wrote on last edited by
        #7

        If you invoke moc manually on your header file, does it generate the needed code? If so (and I see no reason why it should not), you have a problem with your build system. I am not experienced with cmake, so I can't help you with that, but i will guarantee you that Volker is right and you must let moc generate the signals implementation for you.

        1 Reply Last reply
        0
        • D Offline
          D Offline
          dnadave
          wrote on last edited by
          #8

          moc does generate the needed code when called by hand.

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #9

            Then your problem is with your project definition in cmake, or with cmake itself somehow. Perhaps you can get better assistance in a cmake specific channel.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              dnadave
              wrote on last edited by
              #10

              I'm not quite convinced it's cmake yet. I just did the following:

              @

              moc QDSlider.h > moc_QSlider.cpp
              @

              and then added moc_QSlider.cpp to the list of source files for compilation thinking that maybe the moc file was compiled, but not linked.

              I then get the following error:

              @
              Linking CXX shared library libgsdesigngui.so
              CMakeFiles/gsdesigngui.dir/moc_QDSlider.cxx.o: In function QDSlider::metaObject() const': moc_QDSlider.cxx:(.text+0x0): multiple definition of QDSlider::metaObject() const'
              CMakeFiles/gsdesigngui.dir/moc_QSlider.cpp.o:moc_QSlider.cpp:(.text+0x0): first defined here
              CMakeFiles/gsdesigngui.dir/moc_QDSlider.cxx.o:(.data.rel.ro+0x0): multiple definition of QDSlider::staticMetaObject' CMakeFiles/gsdesigngui.dir/moc_QSlider.cpp.o:(.data.rel.ro+0x0): first defined here CMakeFiles/gsdesigngui.dir/moc_QDSlider.cxx.o: In function QDSlider::qt_metacast(char const*)':
              moc_QDSlider.cxx:(.text+0x20): multiple definition of QDSlider::qt_metacast(char const*)' CMakeFiles/gsdesigngui.dir/moc_QSlider.cpp.o:moc_QSlider.cpp:(.text+0x20): first defined here CMakeFiles/gsdesigngui.dir/moc_QDSlider.cxx.o: In function QDSlider::valueChanged(double)':
              moc_QDSlider.cxx:(.text+0x70): multiple definition of QDSlider::valueChanged(double)' CMakeFiles/gsdesigngui.dir/moc_QSlider.cpp.o:moc_QSlider.cpp:(.text+0x70): first defined here CMakeFiles/gsdesigngui.dir/moc_QDSlider.cxx.o: In function QDSlider::qt_metacall(QMetaObject::Call, int, void**)':
              moc_QDSlider.cxx:(.text+0xb0): multiple definition of `QDSlider::qt_metacall(QMetaObject::Call, int, void**)'
              CMakeFiles/gsdesigngui.dir/moc_QSlider.cpp.o:moc_QSlider.cpp:(.text+0xb0): first defined here
              collect2: ld returned 1 exit status
              @

              The file moc_QSlider.cpp contained:

              @
              GSDesignGUI/package> cat gsDesignExplorer/src/explorergui/moc_QSlider.cpp
              /****************************************************************************
              ** Meta object code from reading C++ file 'QDSlider.h'
              **
              ** Created:
              ** by: The Qt Meta Object Compiler version 62 (Qt 4.7.1)
              **
              ** WARNING! All changes made in this file will be lost!
              *****************************************************************************/

              #include "../explorergui/QDSlider.h"
              #if !defined(Q_MOC_OUTPUT_REVISION)
              #error "The header file 'QDSlider.h' doesn't include <QObject>."
              #elif Q_MOC_OUTPUT_REVISION != 62
              #error "This file was generated using the moc from 4.7.1. It"
              #error "cannot be used with the include files from this version of Qt."
              #error "(The moc has changed too much.)"
              #endif

              QT_BEGIN_MOC_NAMESPACE
              static const uint qt_meta_data_QDSlider[] = {

              // content:
              5, // revision
              0, // classname
              0, 0, // classinfo
              2, 14, // methods
              0, 0, // properties
              0, 0, // enums/sets
              0, 0, // constructors
              0, // flags
              1, // signalCount

              // signals: signature, parameters, type, tag, flags
              10, 9, 9, 9, 0x05,

              // slots: signature, parameters, type, tag, flags
              31, 9, 9, 9, 0x08,

                 0        // eod
              

              };

              static const char qt_meta_stringdata_QDSlider[] = {
              "QDSlider\0\0valueChanged(double)\0"
              "setValue(double)\0"
              };

              const QMetaObject QDSlider::staticMetaObject = {
              { &QSlider::staticMetaObject, qt_meta_stringdata_QDSlider,
              qt_meta_data_QDSlider, 0 }
              };

              #ifdef Q_NO_DATA_RELOCATION
              const QMetaObject &QDSlider::getStaticMetaObject() { return staticMetaObject; }
              #endif //Q_NO_DATA_RELOCATION

              const QMetaObject *QDSlider::metaObject() const
              {
              return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
              }

              void QDSlider::qt_metacast(const char _clname)
              {
              if (!_clname) return 0;
              if (!strcmp(_clname, qt_meta_stringdata_QDSlider))
              return static_cast<void
              >(const_cast< QDSlider
              >(this));
              return QSlider::qt_metacast(_clname);
              }

              int QDSlider::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
              {
              _id = QSlider::qt_metacall(_c, _id, _a);
              if (_id < 0)
              return _id;
              if (_c == QMetaObject::InvokeMetaMethod) {
              switch (_id) {
              case 0: valueChanged((reinterpret_cast< double()>(_a[1]))); break;
              case 1: setValue((reinterpret_cast< double()>(_a[1]))); break;
              default: ;
              }
              _id -= 2;
              }
              return _id;
              }

              // SIGNAL 0
              void QDSlider::valueChanged(double _t1)
              {
              void _a[] = { 0, const_cast<void>(reinterpret_cast<const void*>(&_t1)) };
              QMetaObject::activate(this, &staticMetaObject, 0, _a);
              }
              QT_END_MOC_NAMESPACE
              @

              I'll keep looking at my CMakelist.txt file, but I'm not yet convinced that this is where the problem is.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andre
                wrote on last edited by
                #11

                So... try it out (with the same sources) with qmake. If that works ok, then the problem is cmake.

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  goetz
                  wrote on last edited by
                  #12

                  setDouble() is a slot, you must implement this manually.

                  It's only the signals that must not be implemented manually, but are implemented by moc autogenerated code.

                  http://www.catb.org/~esr/faqs/smart-questions.html

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    dnadave
                    wrote on last edited by
                    #13

                    Ah! OK, so I implemented my QDSlider slot as follows and connected it to the QDSpinBox as follows, as well.

                    qdslider.h
                    @
                    #define QDSLIDER_H

                    #include <QSlider>

                    class QDSlider : public QSlider
                    {
                    Q_OBJECT
                    public:
                    explicit QDSlider();
                    explicit QDSlider( QWidget * );
                    explicit QDSlider( Qt::Orientation , QWidget * );
                    signals:
                    void valueChanged( double );
                    private slots:
                    void setValue( double );
                    };

                    #endif
                    @

                    qdslider.cpp
                    @
                    #include "qdslider.h"

                    QDSlider::QDSlider():QSlider() {}
                    QDSlider::QDSlider( QWidget *parent = 0 ):QSlider( parent ) {}
                    QDSlider::QDSlider( Qt::Orientation orientation , QWidget *parent = 0 ):QSlider( orientation , parent ) {}

                    void QDSlider::setValue( double value )
                    {
                    int ivalue = value;
                    emit QSlider::setValue( ivalue );
                    }
                    @

                    connect code in main program:
                    @
                    QObject::connect( ui->anlErrorDSpin , SIGNAL( valueChanged( double ) ) ,
                    ui->anlErrorHSlider , SLOT( setValue( double ) ) );
                    QObject::connect( ui->anlErrorHSlider , SIGNAL( valueChanged( double ) ) ,
                    ui->anlErrorDSpin , SLOT( setValue( double ) ) );
                    @

                    This compiles, links, and loads. The problem is that when I run the program, I get the following error:

                    @
                    Object::connect: No such slot QSlider::setValue( double )
                    Object::connect: (sender name: 'anlErrorDSpin')
                    Object::connect: (receiver name: 'anlErrorHSlider')
                    Object::connect: No such signal QSlider::valueChanged( double )
                    Object::connect: (sender name: 'anlErrorHSlider')
                    Object::connect: (receiver name: 'anlErrorDSpin')
                    @

                    Why is the compiled code looking for QSlider::setValue( double ) when anlErrorHSlider is defined as a QDSlider which does have a setValue( double ) defined? I tried doing the following:

                    @
                    QObject::connect( ui->anlErrorDSpin , SIGNAL( valueChanged( double ) ) ,
                    ui->anlErrorHSlider , SLOT( QDSlider::setValue( double ) ) );
                    @

                    which resulted in the following error at run time:

                    @
                    Object::connect: No such slot QSlider::QDSlider::setValue( double )
                    Object::connect: (sender name: 'anlErrorDSpin')
                    Object::connect: (receiver name: 'anlErrorHSlider')
                    @

                    What do I have to do to get the right setValue called?!?

                    1 Reply Last reply
                    0
                    • D Offline
                      D Offline
                      dnadave
                      wrote on last edited by
                      #14

                      Figured out why the wrong setValue was being used. the ui_xxx.h file was not being updated due to the way I was building the project. Once I deleted the offending ui_xxx.h file and pointed the include directory to the right location of the correct ui_xxx.h file, things worked better.

                      Now to set the signals such that updating the slider changes the spinbox and the reverse...

                      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