我想有一个调用相应子类函数的插槽。这是一个演示:
#ifndef CALCULATORFORM_H
#define CALCULATORFORM_H
#include <QMainWindow>
#include <iostream>
#include "ui_form.h"
class MainWindow : public QMainWindow, public Ui::MainWindow
{
Q_OBJECT
signals:
void valueChanged(int);
private slots:
void on_horizontalSlider_valueChanged(int value)
{
SliderValueChanged(value);
}
public:
MainWindow(QMainWindow *parent = 0)
{
this->setupUi(this);
bool success = connect(this->horizontalSlider, SIGNAL(valueChanged(int)), this, SLOT(on_horizontalSlider_valueChanged(int)));
std::cout << "Success? " << success << std::endl;
}
//private:
virtual void SliderValueChanged(const int value)
{
std::cout << "MainWindow" << std::endl;
}
};
class FloatSlider : public MainWindow
{
Q_OBJECT
public:
FloatSlider(QMainWindow *parent = 0) : MainWindow(parent){this->setupUi(this);}
private:
void SliderValueChanged(const int value)
{
std::cout << "FLOAT" << std::endl;
}
};
#endif
如果我使用MainWindow,它会在移动滑块时正确输出“MainWindow”。但是,如果我使用FloatSlider,则不输出任何内容。谁能看到我做错了什么?
答案 0 :(得分:3)
您的问题是,您在setupUi
构造函数和MainWindow
构造函数中都调用了FloatSlider
。但FloatSlider
没有自己的ui部分,它继承了MainWindow
中的那个。
因此,您在MainWindow
构造函数中设置了ui并建立连接。然后在FloatSlider
构造函数中,当MainWindow
构造函数完成后,再次调用setupUi
,它会覆盖ui对象(或者更确切地说是相应的指针,因为组件都是动态的创建)与新的,现在没有连接。这就是为什么它在connect
构造函数中调用FloatSlider
时也能正常工作的原因。但当然它仍然会造成内存泄漏(来自第一个setupUi
调用的对象丢失)。实际上旧的对象可能会被Qt清理掉,因为它们仍然有this
作为父对象,但它们只是没用,因为它们要么无处可闲(如果窗口有顶级布局,则会被覆盖在setupUi
而不是添加)或者它们是重复的(如果窗口没有顶级布局)。
所以只需从setupUi
的构造函数中删除此FloatSlider
调用即可。由于MainWindow
继承自Ui::MainWindow
而FloatSlider
未添加setupUi
所关注的任何内容,因此MainWindow
有责任致电setupUi
。