3

这段代码:

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::connect:QCPAxis::MyAxis::rescale(QCPRange)plotwindow.cpp: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:没有任何区别。

4

4 回答 4

1

您不能只将现有轴转换为MyAxis*. 您需要实例化一个新的MyAxis并将其分配给图形:

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

未来提示:避免static_cast<>()有检查选项的地方(这里qobject_cast<>(),,否则dynamic_cast<>())。这将有助于识别无效的假设。

于 2016-06-22T08:58:07.880 回答
1

Qt 存储了一些关于继承自QObject. 这些信息之一是类的插槽。通过静态转换对象,这些元信息不会在转换中更新,因此您的转换对象的元信息不包含您在MyAxis类中实现的插槽。这就是为什么它无法在运行时将信号连接到投射对象。即使您在MyAxis类中重新实现了一个虚拟槽,通过静态转换您的对象,新转换的对象的槽指向旧槽并且不会升级为指向重新实现的槽。

更新:通过使用qobject_cast(这是 Qt 对象的安全转换方式),您可以看到转换的对象为 NULL。

于 2016-06-22T09:17:32.653 回答
1

我认为你在这里尝试做的事情有问题:

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

返回一个QCPAxis而不是一个MyAxis类。假设 QCPAxiz 占用 100 字节的内存,而 MyAxis 占用 110 字节,那么您正在尝试这样做:

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

我不明白这怎么行。您正在调用的函数返回一个 QCPAxis 并且您不能仅仅因为它们共享相同的基类而将其转换为 MyAxis ......这有点像拥有福特嘉年华并说,“现在它是法拉利” 只是因为它们具有相同的“汽车”基本类型。

所以目前我认为你陷入了未定义的行为......

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

于 2016-06-22T06:41:21.033 回答
-1
  1. Qt 的 moc-generator 非常严格:所以使用相同的签名:

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

        Q_DECLARE_METATYPE(QCPRange)
    
于 2016-06-22T09:45:04.393 回答