Поиск:

Ответ в темуСоздание новой темы Создание опроса
> MMFrame::QGraphicsObject - проблема со слотом 
:(
    Опции темы
wowka19
Дата 14.4.2014, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



Есть класс MMFrame, который раньше наследовал QGraphicsItem. Все работало без проблем.
Понадобилось "void MMFrame::метод(qreal)" сделать слотом - я поменял родителя на QGraphicsObject, добавил макрос Q_OBJECT в private-секцию и переместил void MMFrame::метод(qreal) в секцию public slots. Больше ничего не менял. Теперь, даже не связывая слот ни с чем, при сборке линкер выдает ошибки:

MMFrame.obj:-1: ошибка: LNK2001: неразрешенный внешний символ ""public: virtual struct QMetaObject const * __thiscall MMFrame::metaObject(void)const " (?metaObject@MMFrame@@UBEPBUQMetaObject@@XZ)"

MMFrame.obj:-1: ошибка: LNK2001: неразрешенный внешний символ ""public: virtual void * __thiscall MMFrame::qt_metacast(char const *)" (?qt_metacast@MMFrame@@UAEPAXPBD@Z)"

MMFrame.obj:-1: ошибка: LNK2001: неразрешенный внешний символ ""public: virtual int __thiscall MMFrame::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@MMFrame@@UAEHW4Call@QMetaObject@@HPAPAX@Z)"

debug\FrameTest.exe:-1: ошибка: LNK1120: 3 неразрешенных внешних элементов

Проект очищал/пересобирал - без толку. Что не так?


На всякий случай код класса (не включает в себя сторонних либ, поэтому можно пробовать скомпилить у себя) Qt v4.8.5:

Код

#ifndef MMFRAME_H
#define MMFRAME_H

#include <QtGui>
#include <QGraphicsObject>

enum MM_FRAME_PART
{
    MM_FP_NONE = 0,
    MM_FP_CENTER,
    MM_FP_TOP,
    MM_FP_BOTTOM,
    MM_FP_LEFT,
    MM_FP_RIGHT,
    MM_FP_TOP_LEFT,
    MM_FP_TOP_RIGHT,
    MM_FP_BOTTOM_LEFT,
    MM_FP_BOTTOM_RIGHT
};

class MMFrame : public QGraphicsObject
{
    Q_OBJECT

public:
    MMFrame(const QRectF& rect, qreal borderWidth = 10.0, qreal step = 1.0, QGraphicsItem* parent = 0);

    virtual QRectF boundingRect() const;
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    void moveTop(qreal delta);
    void moveBottom(qreal delta);
    void moveLeft(qreal delta);
    void moveRight(qreal delta);

    QRectF describedArea() const;

public slots:
    void adaptIgnoringScalingParts(qreal scalingFactor);

protected:
    virtual void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    virtual void keyPressEvent(QKeyEvent *event);

private:
    MM_FRAME_PART underCursorFramePart(const QPointF &point);
    void moveSelectedFramePart(const QPointF &deltaPos); //moveOrResize(const QPointF &deltaPos) ???

    const qreal borderWidth_;
    qreal scaledBorderWidth_;
    qreal width_;
    qreal height_;
    const qreal step_;
    qreal scaledStep_;
    MM_FRAME_PART selectedFramePart_;
};

#endif // MMFRAME_H




Код

#include "MMFrame.h"


MMFrame::MMFrame(const QRectF& rect, qreal borderWidth, qreal step, QGraphicsItem *parent)
    :QGraphicsObject(parent)
    ,width_(rect.width())
    ,height_(rect.height())
    ,borderWidth_(borderWidth)
    ,scaledBorderWidth_(borderWidth)
    ,step_(step)
    ,scaledStep_(step)
    ,selectedFramePart_(MM_FP_NONE)
{
    setPos(rect.topLeft());
    setAcceptHoverEvents(true);
    setFlag(ItemIsMovable);
    setFlag(ItemIsFocusable);
    setZValue(1);
}

QRectF MMFrame::boundingRect() const
{
    return QRectF(-scaledBorderWidth_, -scaledBorderWidth_, width_+scaledBorderWidth_*2, height_+scaledBorderWidth_*2);
}

void MMFrame::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->save();

    painter->setPen(Qt::NoPen);
    painter->setBrush(QBrush(Qt::black, Qt::SolidPattern));
    //left
    painter->drawRect(-scaledBorderWidth_,-scaledBorderWidth_,scaledBorderWidth_,height_+scaledBorderWidth_*2);
    //top
    painter->drawRect(0,-scaledBorderWidth_,width_,scaledBorderWidth_);
    //bottom
    painter->drawRect(0,height_,width_,scaledBorderWidth_);
    //right
    painter->drawRect(width_,-scaledBorderWidth_,scaledBorderWidth_,height_+scaledBorderWidth_*2);

    painter->restore();
}

QRectF MMFrame::describedArea() const
{
    return QRectF(x(), y(), width_, height_);
}

MM_FRAME_PART MMFrame::underCursorFramePart(const QPointF &point)
{
    qreal X = point.x();
    qreal Y = point.y();

    if (X < 0)
    {
        if (Y < 0) return MM_FP_TOP_LEFT;
        else if (Y < height_) return MM_FP_LEFT;
        else return MM_FP_BOTTOM_LEFT;
    }
    else if (X < width_)
    {
        if (Y < 0) return MM_FP_TOP;
        else if (Y < height_) return MM_FP_CENTER;
        else return MM_FP_BOTTOM;
    }
    else
    {
        if (Y < 0) return MM_FP_TOP_RIGHT;
        else if (Y < height_) return MM_FP_RIGHT;
        else return MM_FP_BOTTOM_RIGHT;
    }
}

void MMFrame::hoverMoveEvent(QGraphicsSceneHoverEvent * event)
{
    MM_FRAME_PART framePart = underCursorFramePart(event->pos());

    if (framePart == MM_FP_TOP_LEFT || framePart == MM_FP_BOTTOM_RIGHT) setCursor(Qt::SizeFDiagCursor);
    else if (framePart == MM_FP_TOP_RIGHT || framePart == MM_FP_BOTTOM_LEFT) setCursor(Qt::SizeBDiagCursor);
    else if (framePart == MM_FP_TOP || framePart == MM_FP_BOTTOM) setCursor(Qt::SizeVerCursor);
    else if (framePart == MM_FP_LEFT || framePart == MM_FP_RIGHT) setCursor(Qt::SizeHorCursor);
    else setCursor(Qt::SizeAllCursor); //setCursor(Qt::ArrowCursor);
}

void MMFrame::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    selectedFramePart_ = underCursorFramePart(event->pos());
}

void MMFrame::keyPressEvent(QKeyEvent *event)
{
    QPointF deltaPos(0.0, 0.0);

    switch (event->key())
    {
    case Qt::Key_Up: deltaPos.ry() -= scaledStep_; break;
    case Qt::Key_Down: deltaPos.ry() += scaledStep_; break;
    case Qt::Key_Left: deltaPos.rx() -= scaledStep_; break;
    case Qt::Key_Right: deltaPos.rx() += scaledStep_; break;
    default: break;
    }

    moveSelectedFramePart(deltaPos);
}

void MMFrame::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    moveSelectedFramePart(event->scenePos() - event->lastScenePos());
}

void MMFrame::moveSelectedFramePart(const QPointF &deltaPos)
{
    qreal dX = deltaPos.x();
    qreal dY = deltaPos.y();

    switch (selectedFramePart_)
    {
    case MM_FP_CENTER:
        setPos(pos()+deltaPos);
        break;
    case MM_FP_TOP_LEFT:
        moveTop(dY);
        moveLeft(dX);
        break;
    case MM_FP_TOP:
        moveTop(dY);
        break;
    case MM_FP_TOP_RIGHT:
        moveTop(dY);
        moveRight(dX);
        break;
    case MM_FP_LEFT:
        moveLeft(dX);
        break;
    case MM_FP_RIGHT:
        moveRight(dX);
        break;
    case MM_FP_BOTTOM_LEFT:
        moveBottom(dY);
        moveLeft(dX);
        break;
    case MM_FP_BOTTOM:
        moveBottom(dY);
        break;
    case MM_FP_BOTTOM_RIGHT:
        moveBottom(dY);
        moveRight(dX);
        break;
    default: break;
    }
}

void MMFrame::adaptIgnoringScalingParts(qreal scalingFactor)
{
    prepareGeometryChange();
    scaledBorderWidth_ = borderWidth_ / scalingFactor;
    scaledStep_ = step_ / scalingFactor;
}

void MMFrame::moveTop(qreal delta)
{
    if (height_ > delta)
    {
        prepareGeometryChange();
        height_ -= delta;
        setY(y() + delta);
    }
}

void MMFrame::moveBottom(qreal delta)
{
    if (height_ > -delta)
    {
        prepareGeometryChange();
        height_ += delta;
    }
}

void MMFrame::moveLeft(qreal delta)
{
    if (width_ > delta)
    {
        prepareGeometryChange();
        width_ -= delta;
        setX(x() + delta);
    }
}

void MMFrame::moveRight(qreal delta)
{
    if (width_ > -delta)
    {
        prepareGeometryChange();
        width_ += delta;
    }
}



Это сообщение отредактировал(а) wowka19 - 14.4.2014, 22:40
PM MAIL   Вверх
Guinness
Дата 15.4.2014, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 310
Регистрация: 21.6.2009
Где: Зеленоград

Репутация: 2
Всего: 10



Если работаешь с QtCreator,  просто передобавь данный класс в проект. У тебя moc-компилятор не обрабатывает данный файл.
PM MAIL   Вверх
wowka19
Дата 16.4.2014, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 30.11.2011

Репутация: нет
Всего: нет



спасибо, помогло!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0405 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.