Сделать слот вызовом виртуальной функции - PullRequest
2 голосов
/ 05 декабря 2011

Я хотел бы иметь слот, который вызывает функцию соответствующего подкласса. Вот демо:

#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 Ответ

3 голосов
/ 05 декабря 2011

Ваша проблема в том, что вы вызываете setupUi как в конструкторе MainWindow, так и в конструкторе FloatSlider. Но FloatSlider не имеет своей собственной части пользовательского интерфейса, она наследует от MainWindow.

Итак, вы настраиваете пользовательский интерфейс в конструкторе MainWindow и устанавливаете соединение. Затем в конструкторе FloatSlider, который следует после завершения конструктора MainWindow, вы снова вызываете setupUi, который перезаписывает объекты пользовательского интерфейса (или, скорее, соответствующие указатели, так как все компоненты динамически создаются) новыми, которые сейчас не имеют связи. Вот почему это работает, когда вы вызываете connect и в конструкторе FloatSlider. Но, конечно, это все же создает утечку памяти (объекты из первого вызова setupUi теряются). На самом деле старые объекты могут быть очищены Qt, потому что они все еще имеют this в качестве родителя, но они просто бесполезны, так как они либо никуда не деваются (если окно имеет макет верхнего уровня, который перезаписывается в setupUi вместо добавленного) или они дублируются (если окно не имеет разметки верхнего уровня).

Так что просто удалите этот вызов setupUi из конструктора FloatSlider. Поскольку MainWindow наследуется от Ui::MainWindow, а FloatSlider не добавляет ничего, о чем setupUi заботится, MainWindow несет ответственность за вызов setupUi.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...