Qt сигналы и вопрос наследования - PullRequest
12 голосов
/ 10 мая 2009

Я относительно новичок в программировании на Qt и у меня возник вопрос. Короткая версия:

Как мне наследовать сигналы, определенные в суперклассах?

Я пытаюсь создать подкласс QTWidget другого пользователя, чтобы изменить поведение по умолчанию:


//Plot3D is a QWidget that defines a signal "rotationChanged"
class matLinePlot : public QObject, public Plot3D {

    Q_OBJECT;
        //etc...
public:
       //etc...

        //Catch Plot3D's signal "rotationChanged" and do some magic with it:
    void initPlot(){
              QObject::connect(this, SIGNAL(rotationChanged( double , double , double )),
            this, SLOT(myRotationChanged(double, double, double)));
    }
};

Проблема в строке QObject :: connect. То, что я хотел бы сделать, это подключить вращение SIGNAL (из qwt3D_plot.h) к локальной функции / слот - «myRotationChanged». Однако всякий раз, когда я делаю это, во время выполнения я получаю:

Object :: connect: такого сигнала нет matLinePlot :: вращениеChanged (double, double, double)

в C: ... \ matrixVisualization.h. Конечно, я знаю, что rotationChanged не в matrixVisualization.h - это в qwt_plot3D.h, но я подумал, что, поскольку я наследую от Plot3D, все должно быть хорошо. Но теперь, когда я думаю об этом, поскольку SIGNAL и SLOT являются макросами, я предполагаю, что MOC не знает / не заботится о наследовании.

Что приводит меня к моему вопросу - поскольку MOC и SIGNALS / SLOTS, кажется, не знают о наследовании и т. Д .: как я могу создать подкласс виджета, определенного в другом месте, и получить доступ к сигналам виджета?

У меня есть много примеров того, как использовать инкапсуляцию для достижения чего-то подобного, но, боюсь, я не понимаю, как сделать это с наследованием.

Извините, если это нелепый вопрос - я чувствую, что упускаю что-то очевидное.

Ответы [ 4 ]

10 голосов
/ 10 мая 2009

Полагаю, проблема в множественном наследовании:

class matLinePlot : public QObject, public Plot3D
...

Я предполагаю, что Plot3D является подклассом QObject? В этом случае вы должны сделать

class matLinePlot : public Plot3D
...

вместо.

2 голосов
/ 10 мая 2009

SIGNAL (x) и SLOT (x) - это макросы, которые генерируют строковые литералы. Во время выполнения слоты и сигналы сопоставляются с использованием сравнения строк сгенерированных литералов.

(я бы добавил комментарий к комментарию mdec, но мне не хватает представителя)

1 голос
/ 10 мая 2009

Я полагаю, что это будет работать, если сигнал Plot3D :: revolutionChanged является открытым или защищенным. Вы уверены, что сигнал не является частным?

Edit:

Хотя я не смог найти конкретную ссылку, мне придется сделать вывод, что сигналы всегда являются публичными. По крайней мере, тест, который я здесь провел, показал, что я могу подключиться к сигналу, даже если он был объявлен в закрытом разделе класса.

Я также проверил, что сигнал, объявленный в QObject, может быть подключен с использованием подкласса QObject в операторе подключения, поэтому сигналы определенно наследуются. Как я вижу в других ответах и ​​комментариях здесь, проблема должна быть в другом месте.

0 голосов
/ 10 мая 2009

Неправильно -> см. Комментарии.

Я использую Qtopia в Uni, и мне кажется, что я вспоминаю, как кто-то говорил что-то о расстоянии в параметрах SIGNAL и SLOT для соединения.

Попробуйте использовать

QObject::connect(this, SIGNAL(rotationChanged(double,double,double)),
            this, SLOT(myRotationChanged(double,double,double)));

Я знаю, что это не кажется интуитивно понятным, поскольку C ++ не чувствителен к пробелам, однако я считаю, что это как-то связано с магией, которую использует Qtopia / QT при соединении сигналов и слотов. Это может относиться только к Qtopia, или я, возможно, услышал неправильно, но попробуйте. Кроме того, являются ли сигналы общедоступными или защищенными, и вы включили соответствующие файлы заголовков?

...