1

QT State Maschine を構築しようとしています。いくつかの状態があり、それらの状態には、GUI のグラフィックスを変更するトランジションが必要です。私が抱えている問題と私が尋ねている唯一の理由は、私は立ち往生していてポイント1です.

コンパイラは QTEventTransition を識別できません。Windows で QT Creator を使用して QT 4.6 を使用しています。コンパイラはヘッダー #include < QtEventTransition > を検出しません

これは私がしたことです。私はこれをしたことはありませんが、正しいはずだと思います。トランジションが次のように宣言されているヘッダーファイルがあります。

       class validateBoatTransition : public QtEventTransition
    {
    public:
        validateBoatTransition(Widget *widget,ServerSkeleton* server);

    protected:
       bool eventTest(QEvent *e);
       void onTransition(QEvent *);

    private:
       Chart* ourChart;
       Message current;
       BarelySocket* myBarelySocket;
    };

私はこれを持っているCppファイルを持っています:

validateBoatTransition::validateBoatTransition(Widget *widget,ServerSkeleton* server)
{


}


void validateBoatTransition::onTransition(QEvent *e)
{
    /*
  My Logik should go here
*/
}

私が欲しいのは、トランジションがボタン (クリック) によってアクティブ化された場合、このトランジションを起動する必要があるということです!

ネットで調べたのですが、解決策が見つかりません。それをしてもいいですか?と思うべきです。

あなたのトーマス

4

3 に答える 3

0

目標を達成するために間違ったクラス/メカニズムを使用しようとしていると思います。私があなたを正しく理解していれば、いくつかのGUIがあり、いくつかのボタンをクリックした後、いくつかのものを検証したい.この検証が成功した場合、ステートマシンはその状態を変更する必要があります. 私はこのように書きます:

検証を処理するクラスを作成します。

class BoatValidator : public QObject
{
Q_OBJECT

// boring stuff like constructor, etc.

public slots:
    void validate() 
    {
        if ( /*your validation logic goes here*/ ) {
            emit boatTransition();
        }
    }

signals:
    void boatTransition(); // emitted if validation is succesful        
};

次に、QPushButton::clicked() を BoatValidator::validate() に接続し、BoatValidator::boatTransition() シグナルを使用してステート マシンを駆動します。

QStateMachine machine;
QState *state1 = new QState(&machine);
QState *state2 = new QState(&machine);

// more state machine setup

// connect validator and button
QPushButton button;
BoatValidator validator;
connect(&button, SIGNAL(clicked()), &validator, SLOT(validate()));

// use validator to change states
state1->addTransition(&validator, SIGNAL(boatTransition()), state2);

一部のトランジションが明らかにイベント ドリブンでない限り (たとえば、GUI ウィジェットの QEvent::Enter/QEvent::Leave など)、通常はシグナルを使用してステート マシンを駆動します。

于 2010-04-08T07:13:03.673 に答える
0

私がやりたかったのは、Qt ステート マシンを構築することです。問題は、自分のトランジションをトリガーできないことでした (自分のイベントは言うまでもなく)。与えられた答えは良いですが、コードが乱雑になります。QT トランジションを使用できないのに QT ステート マシンを使用する必要があるのはなぜですか? 上記の最初の問題は、新しいプロジェクトを作成すると解決されます。QT クリエーターは非常に面倒です。しかし、ここで私の解決策が他の人に役立つかもしれません。

最初に私の状態:

class ServerState : public QState
{
    Q_OBJECT

public:
    ServerState(QPushButton * pushButton);
    ~ServerState();

public slots:
    void buttonWasClicked();

protected:
    void onEntry(QEvent *e);
    void onExit(QEvent *e);

private:
    QPushButton * pushButton;
};

通常ですが、スロットを追加したことがわかります。このスロットにより、ボトム信号またはウィジェット マウス プレス信号を接続できます。
このような:

QStateMachine *machine = new QStateMachine(this);
ServerState *s1 = new ServerState(connectButton);
connect(connectButton, SIGNAL(clicked()), s1, SLOT(buttonWasClicked()));
machine->addState(s1);
s1->addTransition(connectTransition);

私がする必要があるのは、次のような宣言されたイベントを発生させることだけです:

#define RegisterToServerEventIndex User+5
class ConnectToServerEvent : public QEvent
{
public:
    ConnectToServerEvent() : QEvent(QEvent::Type(QEvent::ConnectToServerEventIndex))
    {}
};

スロットが呼び出されたとき:

void ServerState::buttonWasClicked()
{
    this->machine()->postEvent(new ConnectToServerEvent());
    qDebug("ServerState::buttonWasClicked");
}

QT ステート マシンは、すべての Transitions を呼び出し、この状態にリンクします。

ConnectToServerTransition::ConnectToServerTransition(QPushButton * pushButtonB,ServerSkeleton* serverSkeleton)
{
    this->pushButtonB = pushButtonB;
    this->pushButtonB->hide();
    this->serverSkeleton  = serverSkeleton;
    qDebug("ConnectToServerTransition::ConnectToServerTransition");
}

bool ConnectToServerTransition::eventTest(QEvent *e)
{
    return  (e->type() == QEvent::ConnectToServerEventIndex);
}

void ConnectToServerTransition::onTransition(QEvent *e)
{
    if (true ==  this->serverSkeleton->initalisieren())
    {
        this->pushButtonB->show();
    }else{
        qDebug("Conection to Server faild");
    }
    emit kill();
    return;
}

あえて投稿するほど素晴らしいものは何ですか?まず、Qt SM をウィジェットにリンクして、マウス プレス イベントまたはその他の何かが呼び出され、生データを後でプログラムで必要なレベルに処理できます。あとは、シグナルを発行するだけです。

void Widget::mousePressEvent(QMouseEvent *event){
    Coordinates current;
    current.line = 0;
    current.row = A;
    current.row = (Row) (event->x() / 30); // 30 = breite von einen Feld
    current.line = event->y() / 30; // 30 = länge von einen Feld
    emit this->clicked(current);
    return;
}

次に、この強化された情報 (現在) が、作業を行う正しいトランジションを呼び出すことを選択した状態のスロットに渡されます。必要に応じて、さらにトランジションをリンクできます。

しかし、最も重要なのは、トランジションを再プログラムする必要がないことです。これは、私が本当に嫌いだと思います。

助けてくれてありがとう、私はそれを一人ではできませんでした。

于 2010-04-12T11:30:04.850 に答える
0

たぶん、シグナル/スロットメカニズムに目を向けるべきです。これは、あなたが望むものを達成するために必要なものだと思います。

関数をonTransitionイベント ハンドラーではなくスロットにしてclicked、ボタンのシグナルに接続します。

class validateBoatTransition : public QtEventTransition { ...

public slots:
    void onTransition();

...

}

コードのどこかで、ボタンをスロットに接続します。

QObject::connect(myButton, signal(clicked()), myValidateBoatTransition, slot(onTransition());

ボタンがクリックされるたびに、onTransition 関数が実行されます。

于 2010-04-07T23:15:33.760 に答える