2010-04-07 38 views
1

我正在嘗試構建QT狀態機。我有一些國家,對於那些我需要過渡的國家來改變我的貴族圖形。 這個問題我有我唯一的問題,我卡住了,點1.QT EventTransition實現

編譯器不能識別QTEventTransition。我在Windows上使用QT Creator進行QT 4.6操作。 編譯器不找頭#包括< QtEventTransition>

這是我做的,我從來沒有這樣做bevor但我認爲它應該是正確的,我有一個頭文件在那裏我有我的視線Declareted這樣的:

 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 
*/ 
} 

我想的是,如果轉換是通過按鈕(點擊)激活它應該觸發這種轉變!

我搜索了網絡,但無法找到解決方案。我可以那樣做嗎?我應該想。

你的Thomas

回答

0

我想要做的是構建一個Qt狀態機。問題是我無法觸發我自己的轉換(更不用說我自己的事件了)。給出的答案很好,但會導致一個混亂的代碼。如果我不能使用QT轉換,爲什麼我應該使用QT狀態機? 上面的第一個問題已解決,如果您創建一個新的項目。 QT Creater非常煩人。 但現在我的解決方案,可以幫助別人。

首先我州:

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; 
}; 

正常的,但你看我增加了一個插槽。這個插槽使我能夠連接底部信號或Widget鼠標按壓信號!
像這樣:

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國家機器現在會調用所有的轉換,與此狀態鏈接:

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; 
} 

那麼這個enhenced信息(當前)傳遞給插槽在我的國家,在這裏我選擇來調用正確的過渡,做的工作。如果您需要,您可以將更多轉換鏈接到它。

但最重要的是你不需要重新編程過渡,一想到我真的不喜歡。

謝謝你的幫助,我無法單獨完成。

+0

該解決方案正確,但自定義狀態是不必要的。 QSignalTransition可以用來連接你的按鈕和機器。你可以在自定義轉換的eventTest中攔截'QStateMachine :: SignalEvent'。 'SignalEvent :: arguments'可以讓你訪問信號的參數,你需要測試它們。您也可以在那裏測試其他條件。 – 2015-09-11 15:15:24

0

也許你應該看看signal/slot機制。我認爲這是你需要達到你想要的。

使您的onTransition功能成爲插槽而不是事件處理程序,並將其連接到按鈕的信號clicked

類validateBoatTransition:公共QtEventTransition { ...

public slots: 
    void onTransition(); 

... 

}

某處在你的代碼,該按鈕連接到插槽:

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

每次按鈕將被點擊執行將通過onTransition函數。

+0

這就是我所擁有的。 但它變得混亂。我沒有按鈕。這是我程序的一部分。 – Thomas 2010-04-08 08:52:51

0

我想你正在嘗試使用錯誤的類/機制來實現你的目標。如果我正確地理解了你,你有一些圖形用戶界面,點擊你想驗證一些東西的按鈕後,如果驗證成功,狀態機應該改變它的狀態。我會寫這樣說:

創建一些類來處理驗證:

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 ::點擊()來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); 

一般來說,我會使用信號來驅動狀態機,除非有些轉變是明顯的事件驅動(如某些QEvent的:: ENTER/QEvent的::關於GUI控件離開,等等。)。

+0

謝謝你,你的想法工作得很好。但是現在代碼仍然像以前一樣混亂。如果轉換不會改變狀態,它看起來像浪費代碼 – Thomas 2010-04-08 17:09:15

+0

是的,使用QStateMachine的代碼有時可能會變得混亂,而且我沒有經過測試的解決方案可以使它更清晰。我不明白你對「轉換」中的「代碼浪費」的評論 - 你在說什麼? – chalup 2010-04-08 18:49:00