使插槽调用为虚函数

时间:2011-12-04 21:33:31

标签: qt qt4

我想有一个调用相应子类函数的插槽。这是一个演示:

#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,则不输出任何内容。谁能看到我做错了什么?

1 个答案:

答案 0 :(得分:3)

您的问题是,您在setupUi构造函数和MainWindow构造函数中都调用了FloatSlider。但FloatSlider没有自己的ui部分,它继承了MainWindow中的那个。

因此,您在MainWindow构造函数中设置了ui并建立连接。然后在FloatSlider构造函数中,当MainWindow构造函数完成后,再次调用setupUi,它会覆盖ui对象(或者更确切地说是相应的指针,因为组件都是动态的创建)与新的,现在没有连接。这就是为什么它在connect构造函数中调用FloatSlider时也能正常工作的原因。但当然它仍然会造成内存泄漏(来自第一个setupUi调用的对象丢失)。实际上旧的对象可能会被Qt清理掉,因为它们仍然有this作为父对象,但它们只是没用,因为它们要么无处可闲(如果窗口有顶级布局,则会被覆盖在setupUi而不是添加)或者它们是重复的(如果窗口没有顶级布局)。

所以只需从setupUi的构造函数中删除此FloatSlider调用即可。由于MainWindow继承自Ui::MainWindowFloatSlider未添加setupUi所关注的任何内容,因此MainWindow有责任致电setupUi