Frank Fritz the Blitz Frank Fritz the Blitz - 1 month ago 21
C++ Question

Qt Unresolved External Symbol

I have classes, ImageLabel, and ChoiceLabel. ChoiceLabel inherits from ImageLabel. When I try to make a new ChoiceLabel, I get an Unresolved External Symbol error. Here are the relevant files:

imagelabel.h

#ifndef IMAGELABEL_H
#define IMAGELABEL_H

#include <QLabel>

class QPixmap;
class QStringList;
class QFileDialog;
class QResizeEvent;

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

protected:
virtual int heightForWidth( int width ) const;
virtual QSize sizeHint() const;
QPixmap scaledPixmap() const;
void setPixmap ( const QPixmap & );
void resizeEvent(QResizeEvent *);

private:
QPixmap pix;
};

#endif // IMAGELABEL_H


choicelabel.h

#ifndef CHOICELABEL_H
#define CHOICELABEL_H

class QStringList;

class ChoiceLabel : public ImageLabel
{
Q_OBJECT
public:
ChoiceLabel();
private:
QStringList *imageFiles;
void mousePressEvent(QMouseEvent *);
void keyPressEvent(QKeyEvent *);
void focusInEvent(QFocusEvent *);
void focusOutEvent(QFocusEvent *);
};

#endif // CHOICELABEL_H


mainwindow.cpp

#include "mainwindow.h"
#include "imagelabel.h"
#include "choicelabel.h"
#include <QGridLayout>

#include <qDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{

choiceLabelA = new ChoiceLabel; //the problem occurs here
resultLabel = new ImageLabel;

centralWidget = new QWidget(this);
this->setCentralWidget(centralWidget);

gridLayout = new QGridLayout(centralWidget);
gridLayout->addWidget(resultLabel);
}


EDIT:

imagelabel.cpp

#include "imagelabel.h"
#include <QDebug>

ImageLabel::ImageLabel(QWidget *parent) :
QLabel(parent)
{
setMinimumSize(250,250);
setAlignment(Qt::AlignCenter | Qt::AlignCenter);
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);

QPixmap initialPixmap(250, 250);
initialPixmap.fill(Qt::black);
setPixmap(initialPixmap);
}

void ImageLabel::setPixmap ( const QPixmap & p)
{
pix = p;
QLabel::setPixmap(scaledPixmap());
}

QPixmap ImageLabel::scaledPixmap() const
{
return pix.scaled(this->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
}

int ImageLabel::heightForWidth( int width ) const
{
return pix.isNull() ? this->height() : ((qreal)pix.height()*width)/pix.width();
}

QSize ImageLabel::sizeHint() const
{
int w = this->width();
return QSize( w, heightForWidth(w) );
}

void ImageLabel::resizeEvent(QResizeEvent *)
{
if(!pix.isNull())
QLabel::setPixmap(scaledPixmap());
}


choicelabel.cpp

#include "choicelabel.h"
#include <QStringList>
#include <QFileDialog>
#include <QFrame>

ChoiceLabel::ChoiceLabel():
imageFiles()
{
setFocusPolicy(Qt::StrongFocus);
}

void ChoiceLabel::mousePressEvent(QMouseEvent *)
{
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFiles);
dialog.setNameFilter("Images (*.png *.jpg)");
dialog.setDirectory("C:/Users/FrankFritz/Desktop/qt/uglypictures");

if (dialog.exec()){
imageFiles = dialog.selectedFiles();
QPixmap pixmap = imageFiles->first();
setPixmap(pixmap);
}
}

void ChoiceLabel::keyPressEvent(QKeyEvent *ev)
{
static int index(0);
if (ev->key() == Qt::Key_Right){
index = (index + 1) % imageFiles->length();
setPixmap( QPixmap(imageFiles->at(index)) );
}
if (ev->key() == Qt::Key_Left){
if (index == 0){
index = imageFiles->length() - 1;
}
else{
index = (index - 1) % imageFiles->length();
}
setPixmap( QPixmap(imageFiles->at(index)) );
}
}

void ChoiceLabel::focusInEvent(QFocusEvent *)
{
setFrameStyle(QFrame::StyledPanel);
}

void ChoiceLabel::focusOutEvent(QFocusEvent *)
{
setFrameStyle(QFrame::NoFrame);
}

Answer

Most probably

ChoiceLabel::ChoiceLabel():
    imageFiles()
{
    setFocusPolicy(Qt::StrongFocus);
}


ChoiceLabel::ChoiceLabel(QWidget *parent): ImageLabel(parent)
{
    setFocusPolicy(Qt::StrongFocus);
}

Forgot to call the base class' constructor. Also forgot to specify a parent QWidget * for ChoiceLabel in its own constructor.

See C++ superclass constructor calling rules for reference.