Russian Qt Forum

Qt => Вопросы новичков => Тема начата: Oleg_IT от Октябрь 17, 2012, 11:30



Название: Ошибка в классе использующий emit.
Отправлено: Oleg_IT от Октябрь 17, 2012, 11:30
Простой тестовый класс, взял из примеров, вместо QDeclarativeItem подставил QLabel.

Код:
#include <QtGui>
class PieChart : public QLabel
{
    Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName)
    Q_PROPERTY(QColor color READ color WRITE setColor)
public:
    PieChart(QLabel *parent = 0);
    QString name() const;
    void setName(const QString &name);
    QColor color() const;
    void setColor(const QColor &color);
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
    Q_INVOKABLE void clearChart();
signals:
    void chartCleared();
private:
    QString m_name;
    QColor m_color;
};
PieChart::PieChart(QLabel *parent)
    : QLabel(parent)
{
    // need to disable this flag to draw inside a QDeclarativeItem
    //setFlag(QGraphicsItem::ItemHasNoContents, false);
}
QString PieChart::name() const
{
    return m_name;
}
void PieChart::setName(const QString &name)
{
    m_name = name;
}
QColor PieChart::color() const
{
    return m_color;
}
void PieChart::setColor(const QColor &color)
{
    m_color = color;
}
void PieChart::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    QPen pen(m_color, 2);
    painter->setPen(pen);
    painter->setRenderHints(QPainter::Antialiasing, true);
    //painter->drawPie(boundingRect(), 90 * 16, 290 * 16);
}
void PieChart::clearChart()
{
    setColor(QColor(Qt::transparent));
    update();
    emit chartCleared();
}

Компилятор выдаёт ошибки
…\TestEmit.cpp:33: ошибка: undefined reference to `vtable for PieChart'
…\TestEmit.cpp:72: ошибка: undefined reference to `PieChart::chartCleared()'

Не пойму проблему. Программа пример, из которой взял код компилится без ошибок.



Название: Re: Ошибка в классе использующий emit.
Отправлено: mutineer от Октябрь 17, 2012, 11:32
Это все в одном файле написано?
Очистить результаты сборки и полностью заново пересобрать (с выполнением qmake) пробовал?


Название: Re: Ошибка в классе использующий emit.
Отправлено: Oleg_IT от Октябрь 17, 2012, 12:11
Пробовал и в одном файле и в разных. Наткнулся на эту проблему когда штатный класс делал в разных файлах, очищал, пересобирал не помогает. MOC-и не создаются. Может где какую галочку поставить нужно?
Сейчас посмотрел, месяц назад делал похожий класс с QAbstractSlider, работает, а принципиальной разницы в классах не вижу.


Название: Re: Ошибка в классе использующий emit.
Отправлено: Vass от Октябрь 17, 2012, 12:41
Если Вы объявляете в cpp файле  класс наследник QObject то в конце файла необходимо сделать
Код:
#inlcude "moc_<имя файла>.cpp"

выглядит странно, но без этого вы получаете ошибки описанные выше.


Название: Re: Ошибка в классе использующий emit.
Отправлено: Bepec от Октябрь 17, 2012, 12:54
Кхм. И вы убиваете возможность использования других IDE. Ибо в VS2008 (проверено) эти строки убьют проект на стадии компиляции :)


Название: Re: Ошибка в классе использующий emit.
Отправлено: Serr500 от Октябрь 17, 2012, 13:05
Разделите интерфейс и реализацию. Интерфейс (объявление) - в h, реализацию - в cpp.


Название: Re: Ошибка в классе использующий emit.
Отправлено: kambala от Октябрь 17, 2012, 13:10
Если Вы объявляете в cpp файле  класс наследник QObject то в конце файла необходимо сделать
Код:
#inlcude "moc_<имя файла>.cpp"

выглядит странно, но без этого вы получаете ошибки описанные выше.
а разве не #inlcude "<имя файла>.moc"?


Название: Re: Ошибка в классе использующий emit.
Отправлено: Bepec от Октябрь 17, 2012, 13:13
Нет. moc делает moc_ИмяФайла.cpp :)


Название: Re: Ошибка в классе использующий emit.
Отправлено: Oleg_IT от Октябрь 17, 2012, 14:07
Цитировать
Если Вы объявляете в cpp файле  класс наследник QObject то в конце файла необходимо сделать
Код:

#inlcude "moc_<имя файла>.cpp"


выглядит странно, но без этого вы получаете ошибки описанные выше.
тут же выдаёт ошибку
ошибка: moc_<имя_файла>.cpp: No such file or directory

И в других, работающих проектах я такой записи не вижу.

Цитировать
ошибка: moc_<имя_файла>.cpp: No such file or directory
Делал так, не помогает.


Убираю Q_OBJECT ошибок нет, но и всё, что касается emit не работает.


Название: Re: Ошибка в классе использующий emit.
Отправлено: mutineer от Октябрь 17, 2012, 14:08
Выложи проект уже, надоело в угадайку играть


Название: Re: Ошибка в классе использующий emit.
Отправлено: Serr500 от Октябрь 17, 2012, 14:30
Ещё раз:
Разделите интерфейс и реализацию. Интерфейс (объявление) - в h, реализацию - в cpp.


Название: Re: Ошибка в классе использующий emit.
Отправлено: Oleg_IT от Октябрь 17, 2012, 15:09
Ошибся
Цитировать
Цитировать
ошибка: moc_<имя_файла>.cpp: No such file or directory
Делал так, не помогает.
Правильно так:
Цитировать
Разделите интерфейс и реализацию. Интерфейс (объявление) - в h, реализацию - в cpp
Делал так, не помогает.



Название: Re: Ошибка в классе использующий emit.
Отправлено: Serr500 от Октябрь 17, 2012, 15:11
Делал так, не помогает.
Проект в студию! Будем посмотреть.


Название: Re: Ошибка в классе использующий emit.
Отправлено: Oleg_IT от Октябрь 18, 2012, 08:36
Прошу прощения, но проект в студию не получится, уже не чего. Какими-то манипуляциями, что-то изменил и проект собрался и заработал. К сожалению я так и не понял, что произошло. Если такая проблема опять возникнет, вопрос вместе с проектом обязательно выложу.


Название: Re: Ошибка в классе использующий emit.
Отправлено: ssoft от Октябрь 18, 2012, 12:32
Просто после разделения на *.h и *.cpp нужно обязательно вызывать qmake. Иначе, все равно не соберется.


Название: Re: Ошибка в классе использующий emit.
Отправлено: Oleg_IT от Октябрь 18, 2012, 14:21
Цитировать
Просто после разделения на *.h и *.cpp нужно обязательно вызывать qmake. Иначе, все равно не соберется.
Так в том то и дело, что изначально ошибка возникла в штатном проекте, где *.h и *.cpp разделены. И очистку и qmake запускал. Видно не в этом дело было. А в одном файле тоже работает, в примерах проект такой есть.