19

シグナルでの型の使用に問題がありenumます。基本的に、ステート マシンとステート マシンを処理するスレッドの 2 つのクラスがあります。状態が変更されたときに、新しい状態で信号を送信したい。また、 を使用して状態を表現したいと考えていenumます。私の本格的なコードでは、ステート マシンは別の共有ライブラリに実装されていますが、以下のコードではまったく同じエラーが発生します。

コードを実行すると、次の動作が得られます。

kotte@EMO-Ubuntu:sigenum $ ./sigenum 
Object::connect: No such slot MyThread::onNewState(state)
Test signal 
Test signal 
...

サンプル コードstatemachine.hには 、statemachine.cppmain.hおよびの 4 つのファイルがありmain.cppます。メイン関数は単純にスレッドを開始し、スレッドは のインスタンスを作成し、StateMachineからのシグナルを処理しますStateMachine。私は Qt にかなり慣れていないので、enum を で囲み、Q_ENUMSそれを型システムに登録する必要があることに気付いたとき、少し戸惑いました。だから私が初歩的なミスを犯した可能性は十分にある

以下のコードは少し長いですが、できるだけ実際のコードに近づけたかったのです。

statemachine.h次のようになります。

// statemachine.h
#ifndef _STATEMACHINE_H
#define _STATEMACHINE_H

#include <QtCore>

class StateMachine : public QObject
{
    Q_OBJECT
    Q_ENUMS(state)

public:
    enum state {S0, S1, S2};

    void setState(state newState);

signals:
    void stateChanged(state newState);
    void testSignal(void);
};

Q_DECLARE_METATYPE(StateMachine::state);

#endif

そしてそれは次のように実装されています:

// statemachine.cpp
#include <QtCore>

#include "statemachine.h"

void StateMachine::setState(state newState)
{
    emit stateChanged(newState);
    emit testSignal();
}

スレッドは次のように定義されます。

// main.h
#ifndef _MAIN_H
#define _MAIN_H

#include <QtCore>

#include "statemachine.h"

class MyThread : public QThread
{
    Q_OBJECT

private:
    void run(void);

private slots:
    void onNewState(StateMachine::state);
    void onTestSignal(void);

private:
    StateMachine *myStateMachine;
};

#endif

そして、それは次のように実装されています。

// main.cpp
#include <QtCore>
#include <QApplication>

#include "statemachine.h"
#include "main.h"

void MyThread::run()
{
    myStateMachine = new StateMachine();

    qRegisterMetaType<StateMachine::state>("state");

    // This does not work
    connect(myStateMachine, SIGNAL(stateChanged(state)),
            this, SLOT(onNewState(state)));

    // But this does...
    connect(myStateMachine, SIGNAL(testSignal()),
            this, SLOT(onTestSignal()));

    forever {
        // ...
        myStateMachine->setState(StateMachine::S0);
    }
}

void MyThread::onTestSignal()
{
    qDebug() << "Test signal";
}

void MyThread::onNewState(StateMachine::state newState)
{
    qDebug() << "New state is:" << newState;
}
4

3 に答える 3

21

どこでも完全修飾名を使用することで、それを機能させることができました

の宣言をに変更したstateChanged()場合

signals:
    void stateChanged(StateMachine::state newState);

そして、タイプをに登録します

qRegisterMetaType<StateMachine::state>("StateMachine::state");

connectまた、ステートメントでこの名前を使用します

connect(myStateMachine, SIGNAL(stateChanged(StateMachine::state)),
        this, SLOT(onNewState(StateMachine::state)));

drescherjmからの入力がなければ、これを解決できなかったでしょう、ありがとう:-)

于 2012-09-11T11:49:01.317 に答える
5

以下は、状態が MyThread クラスで定義されていないと思います。

以下を使用します

connect(myStateMachine, SIGNAL(stateChanged(StateMachine::state)),
            これ、SLOT(onNewState(StateMachine::state)));

編集:

多分これはうまくいくでしょう

connect(myStateMachine, SIGNAL(stateChanged(状態)),
            これ、SLOT(onNewState(StateMachine::state)));
于 2012-09-11T11:34:58.997 に答える