c++ - 在 Qt 的另一个类中发出一个插槽信号

标签 c++ qt signals

情况: 我在 Qt 中有一个 Dialog 类,我在上面绘制了一个正方形光栅。正方形在 MySquare 类(MySquare:QGraphicsItem)中实现。

问题: 我想向 Dialog 插槽 setTarget() 发出一个正方形被单击的信号(显然我想给它一些关于该正方形的信息,例如稍后它的 x 和 y 坐标)。但是,我得到了一个“未定义的对‘MySquare::targetChanged()”的引用错误。我一直在寻找解决方案,但没有找到;有人有想法吗?

编辑:我在 MySquare 中添加了一个 Q_OBJECT 宏,但是错误并没有消失,我得到了一个额外的“'undefined reference to '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;
};

对话框.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);

}

最佳答案

编辑:如果您有一个未定义的 vtable 引用,那么可能是因为您没有实现某些虚函数。您是否在某处实现了 MySquare 类的鼠标事件处理程序?您是否还实现了 MySquare 类的 boundingRect()paint() 函数?

旧答案: 您需要在 MySquare 类中的开头 '{' 之后编写 Q_OBJECT 宏。此外,Qt 有时会提示多重继承。因此,不是从 QGraphicsItemQObject 继承,而是从 QGraphicsObject 继承。

链接器提示缺少函数定义的实际原因如下:当您将 Q_OBJECT 宏放入正确的位置时,Qt 元对象编译器 (MOC) 将生成一个新的项目的 cpp 文件,其中包含相应类的信号函数的定义。所以 Qt 为您实现了每个信号的功能。如果您不插入 Q_OBJECT 宏,则 MOC 不会为您做任何事情,并且链接器将丢失信号的函数定义。

关于c++ - 在 Qt 的另一个类中发出一个插槽信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14172374/

相关文章:

python - C 中的 sighold 和 sigrelse 函数在 Python 中有哪些等价物?

c++ - 如何用stride遍历一个n维数组

c++ - 向 Qt 对话框添加最小化按钮?

c++ - 从 QFileSystemModel 中的文件路径和文件名获取 QModelIndex

events - 忽略 Qt 中的鼠标和键盘事件

audio - 示波器上显示的音频信号上的振铃伪影

c++ - 使用 VNL 读取 MatLab (mat) 文件

c++ - 将字符串分配给结构元素

qt - 使用 QML 显示视频预览/视频缩略图

perl - 如何防止 Windows 捕获 Perl 异常?