1

状況DialogQtに、正方形のラスターを描画するクラスがあります。正方形はMySquareクラス(MySquare:QGraphicsItem)に実装されます。

質問:正方形がクリックされたことをダイアログスロットに通知したいsetTarget()(そして明らかに、後でその正方形のx座標とy座標など、その正方形に関する情報を提供したい)。ただし、「未定義の参照MySquare::targetChanged()」エラーが発生します。私は解決策を探しましたが、見つかりませんでした。誰かアイデア?

編集:MySquare内にQ_OBJECTマクロを追加しましたが、エラーが消えず、追加の「'undefined referenceto'' vtable for MySquare()」エラーが発生します

dialog.h

class Dialog : public QDialog
{
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);

  ~Dialog();


public slots:
    void setTarget();

private:
    Ui::Dialog *ui;
    QGraphicsScene *scene;
};

dialog.cpp

Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog)
{
    ui->setupUi(this);

    scene = new QGraphicsScene(this);
    ui->graphicsView->setScene(scene);

    MySquare *item;

    item = new MySquare(30,30,30,30);
    QObject::connect(item,SIGNAL(targetChanged()),this,SLOT(setTarget()));
}

void Dialog::setTarget(){
    qDebug() << "signal recieved" << endl;
}

mysquare.h

#include <QGraphicsItem>
#include <QPainter>
#include <QDebug>
#include <QKeyEvent>
#include <QObject>

class MySquare : public QGraphicsItem, public QObject
{

Q_OBJECT

public:
    MySquare(int x,int y,int h, int w);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    int x,y,h,w;

signals:
    void targetChanged();

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
};

mysquare.cpp

#include "mysquare.h"
#include <QGraphicsSceneDragDropEvent>
#include <QWidget>

MySquare::MySquare(int _x,int _y, int _w, int _h)
{

    setAcceptDrops(true);
    color=Qt::red;
    color_pressed = Qt::green;
    x = _x;
    y = _y;
    w = _w;
    h = _h;
}


QRectF MySquare::boundingRect() const
{
    return QRectF(x,y,w,h); 
}


void MySquare::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QRectF rec = boundingRect();
    QBrush brush(color);

        if (Pressed){
            brush.setColor(color);
        } else {
            brush.setColor(color_pressed);
        }

    painter->fillRect(rec,brush);
    painter->drawRect(rec);
}


void MySquare::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    Pressed=true;
    update();
    QGraphicsItem::mousePressEvent(event);

    emit targetChanged();
}



void MySquare::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    Pressed=false;
    update();
    QGraphicsItem::mouseReleaseEvent(event);
    qDebug() << "mouse Released";
}

void MySquare::mouseMoveEvent(QGraphicsSceneMouseEvent *event){
    qDebug() << "mouse Moved";
    QDrag *drag = new QDrag(event->widget());
    QMimeData *mime = new QMimeData;
    drag->setMimeData(mime);
    drag->exec();
}


void MySquare::keyPressEvent(QKeyEvent *event){
    //out of bounds check?
    int x = pos().x();
    int y = pos().y();

    QGraphicsItem::keyPressEvent(event);

}
4

2 に答える 2

3

編集: vtable への未定義の参照がある場合は、おそらく特定の仮想関数を実装していないことが原因です。クラスのマウス イベント ハンドラをMySquareどこかに実装しましたか? クラスのboundingRect()およびpaint()関数も実装しましたか?MySquare

古い答え:クラスQ_OBJECTの開始 '{' の後にマクロを記述する必要があります。MySquareまた、Qt はある時点で多重継承について文句を言います。したがって、QGraphicsItemおよびQObjectから継承する代わりに、 から継承しQGraphicsObjectます。

リンカーが関数定義の欠落について文句を言う実際の理由は次のとおりですQ_OBJECT。それぞれのクラスのシグナル関数。したがって、Qt はすべてのシグナルに対して関数を実装します。マクロを挿入しない場合Q_OBJECT、MOC は何も実行せず、シグナルの関数定義がリンカから失われます。

于 2013-01-05T14:02:03.297 に答える
0

次の手順を実行してみてください。

ビルド-クリーン ビルド-実行 qmake ビルド-ビルド。

Q_Object マクロを追加した後、moc オプションが Makefile に設定されていない可能性があります。したがって、Makefile を更新する必要があります。

お役に立てれば。

于 2013-01-07T20:31:27.997 に答える