此代码:
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。
-
QT的MOC生成器非常限制:因此,写作相同签名:
connect(..., SLOT(...(const QCPRange &)));
-
在其中一个H文件中缺少语句:
Q_DECLARE_METATYPE(QCPRange)