[Qt-interest] Problem with undefined VTable when subclassing QSpinBox?

kent williams nkwmailinglists at gmail.com
Fri Jul 23 21:55:18 CEST 2010


Solved it -- I had the Q_OBJECT macro at the start of my class, and
apparently if you define slots or signals that causes this problem.

On Fri, Jul 23, 2010 at 2:17 PM, kent williams
<nkwmailinglists at gmail.com> wrote:
> I know (from web research) that the cause of the undefined external
> for vtable comes from a class not having virtual class member
> functions declared but not defined.   But in this case I can't see
> where I screwed this up.
>
> The problem I was trying to solve was that I wanted to have a QSpinbox
> that would allow the user to choose from a set of predefined choices.
> My particular application was to have a spinbox that allowed the user
> to choose between different Pixel types for an image (unsigned char,
> signed short, signed long, float).
>
> According to the documentation you can do this by deriving a class
> from QSpinBox and redefine valueFromText and textFromValue.  So I did
> so; I'll include the code below.  The problem is that now my
> application fails to link:
>
> Undefined symbols:
>  "vtable for QEnumSpinBox", referenced from:
>      QEnumSpinBox::~QEnumSpinBox()in QEnumSpinBox.cxx.o
>      QEnumSpinBox::QEnumSpinBox(QWidget*)in QEnumSpinBox.cxx.o
>  d: symbol(s) not found
>
> I've spent hours looking at my implementation and I can't see the
> problem. Anyone want to give me some pointers?
>
> --------------------------QEnumSpinBox.h---------------------------------------------------------
>
> #define QEnumspinbox_h
> #include <QSpinBox>
> #include <QValidator>
> #include <QStringList>
>
> class QEnumSpinBox : public QSpinBox
> {
>  Q_OBJECT
> public:
>  QEnumSpinBox(QWidget *parent = 0);
>  virtual ~QEnumSpinBox();
>  void SetValue(const std::string &s);
>  void SetEnumVals(const char **list);
> protected:
>  virtual QValidator::State validate(QString &input, int &pos) const;
>  virtual int valueFromText(const QString &text) const;
>  virtual QString textFromValue(int val) const;
>  virtual void fixup(QString &str) const;
> private:
>  QStringList m_QEnumVals;
> };
>
> #endif // QEnumspinbox_h
> -------------------------------QEnumSpinBox.cxx----------------------------------------------------
>
> #include "QEnumSpinBox.h"
>
> QEnumSpinBox::
> QEnumSpinBox(QWidget *parent) : QSpinBox(parent)
> {
> }
> QEnumSpinBox::
> ~QEnumSpinBox()
> {
> }
>
> QValidator::State
> QEnumSpinBox::
> validate(QString &text, int &pos) const
> {
>  QStringList::const_iterator it;
>  // compare to each QEnum until a match is found or not found
>  for(it = this->m_QEnumVals.constBegin();
>      it != this->m_QEnumVals.constEnd();
>      ++it)
>    {
>    // text substring of current?
>    if(text.size() < (*it).size())
>      {
>      QString tmp((*it));
>      tmp.chop((*it).size() - text.size());
>      if(text == tmp)
>        {
>        return QValidator::Intermediate;
>        }
>      }
>    // exactly equal?
>    else if(text == (*it))
>      {
>      return QValidator::Acceptable;
>      }
>    }
>  return QValidator::Invalid;
> }
>
> void
> QEnumSpinBox::
> SetValue(const std::string &s)
> {
>  QString qs(s.c_str());
>  for(int i = 0; i < this->m_QEnumVals.size(); i++)
>    {
>    if(qs == this->m_QEnumVals[i])
>      {
>      this->setValue(i);
>      break;
>      }
>    }
> }
>
> void
> QEnumSpinBox::
> SetEnumVals(const char **list)
> {
>  for(unsigned i = 0; list[i] != 0; list++)
>    {
>    this->m_QEnumVals.push_back(QString(list[i]));
>    }
> }
>
> int
> QEnumSpinBox::
> valueFromText(const QString &text) const
> {
>  QStringList::const_iterator it;
>  // compare to each QEnum until a match is found or not found
>  unsigned i = 0;
>  for(it = this->m_QEnumVals.constBegin();
>      it != this->m_QEnumVals.constEnd();
>      ++it,++i)
>    {
>    if(text == (*it))
>      {
>      return i;
>      }
>    }
>  return -1;
> }
>
> QString
> QEnumSpinBox::
> textFromValue(int value) const
> {
>
>  if(value < this->m_QEnumVals.size())
>    {
>    return this->m_QEnumVals[value];
>    }
>  return QString("INVALID");
> }
>
> void
> QEnumSpinBox::
> fixup(QString &str) const
> {
>  this->QSpinBox::fixup(str);
> }
>




More information about the Qt-interest-old mailing list