C /否这样的插槽 - 继承

c++/ no such slot - Inheritance

本文关键字:插槽 继承      更新时间:2023-10-16

此代码:

MyAxis *ax;
ax = static_cast<MyAxis*>(ui->customPlot->axisRect()->addAxis(QCPAxis::atLeft));
connect(ui->customPlot->yAxis, SIGNAL(rangeChanged(QCPRange)),
        ax, SLOT(MyAxis::rescale(QCPRange)));

给我这个运行时错误:

qobject ::连接:plotwindow.cpp中没有这样的插槽QCPAxis::MyAxis::rescale(QCPRange):267

通常,当我收到这样的错误时,我将Q_OBJECT宏添加到类中并运行qmake进行修复,但这这次无效。

这是班级的声明:

class MyAxis : public QCPAxis
{
    Q_OBJECT
public:
    void setRefAxis(QCPAxis *refAxis);
    void setScale(double newScale);

public Q_SLOTS:
    virtual void rescale(const QCPRange &range);
private:
    double scale;
    QCPAxis *ref;
};

将声明更改为public slots:没有任何区别。

我认为您在这里试图做的事情有问题:

ui->customPlot->axisRect()->addAxis(QCPAxis::atLeft)

返回QCPAxis,而不是MyAxis类。假设QCPAXIZ需要100个字节的内存,而yaxis则需要110个字节,然后您正在尝试这样做:

A_110_Byte_Type* p110Bytes = static_cast<110-bytes *> (<100-bytes>); // not real code!

我看不出如何工作。您正在调用的函数返回qcpaxis,而您不能仅仅因为它们共享同一基础类别而将其转换为yaxis ...它有点像拥有福特 - 菲斯塔(Ford-fiesta)并说:"现在它是一辆法拉利"仅仅因为它们具有相同的基本类型的"汽车"。

因此,目前我认为您是未定义的行为...

您想做什么? - 您可以将QCPAXI的值复制到您的yryaxis中(使用复制构造函数 - 我认为您需要其中之一来执行此操作)

您不能仅将现有轴施加到MyAxis*。您需要实例化新的MyAxis并将其分配给图表:

QCPGraph *graph = new QCPGraph(this);
MyAxis *ax = new MyAxis(graph);
graph->setValueAxis(ax);
connect(...);

未来的提示:避免使用检查替代方案的static_cast<>()(在此,qobject_cast<>(),否则dynamic_cast<>())。这将有助于确定无效的假设。

qt存储一些从QObject继承的类的元信息。这些信息之一是班级的插槽。通过静态铸造对象,这些元信息不会在铸件中进行更新,因此您的铸造对象的元信息不包含您在MyAxis类中实现的插槽。这就是为什么它不能在运行时将信号连接到铸造的对象的原因。即使您在MyAxis类中重新进来一个虚拟插槽,通过静态铸造对象的静态铸造对象的插槽指向旧插槽,并且不会升级以指向重新成像的插槽。

更新:通过使用qobject_cast(这是QT对象的安全铸造方式),您可以看到它的铸造对象为null。

  1. QT的MOC生成器非常限制:因此,写作相同签名:

    connect(..., SLOT(...(const QCPRange &)));
    
  2. 在其中一个H文件中缺少语句:

        Q_DECLARE_METATYPE(QCPRange)