[Qt-interest] Problem with undefined VTable when subclassingQSpinBox?

Scott Aron Bloom Scott.Bloom at onshorecs.com
Fri Jul 23 22:38:05 CEST 2010


Use qmake..

You need the Q_OBJECT to have signals or slots, and when you have a QObject with signals or slots, you must run moc and link in the results.

Scott

> -----Original Message-----
> From: qt-interest-bounces at trolltech.com [mailto:qt-interest-
> bounces at trolltech.com] On Behalf Of kent williams
> Sent: Friday, July 23, 2010 12:55 PM
> To: QT Interest List
> Subject: Re: [Qt-interest] Problem with undefined VTable when
> subclassingQSpinBox?
> 
> 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);
> > }
> >
> 
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest




More information about the Qt-interest-old mailing list