QT 事件转换实现

发布于 2024-08-28 09:32:05 字数 972 浏览 6 评论 0原文

我正在尝试构建 QT State Maschine。我有一些状态,对于这些状态我需要改变我的图形用户界面上的图形的过渡。 我遇到的问题和我问的唯一原因是,我被卡住了,第 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
*/
}

我想要的是,如果转换由按钮(单击)激活,它应该触发此转换!

我在网上搜索,但找不到解决方案。我可以这样做吗?我应该想。

你的托马斯

I am trying to build an QT State Maschine. I have some States, and for those States i need Transition that alter the Graphics on my gui.
The Problem i having and the only reason i am asking, i am Stuck and Point 1.

The compiler cant identifie the QTEventTransition. I have QT 4.6 wroking with QT Creator on Windows.
The compiler does not find Header #include < QtEventTransition >

This is what i did i never did this bevor but i think it should be correct, I have A Header File where i have my Transitions Declareted like this:

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

Than i have my Cpp File where i have this:

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


}


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

What i want is that if the Transition is activated by an Button (clicked) it should fire this transition!

I searched the net, but cant find an solution. Can i do that? I should i think.

Yours Thomas

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清风不识月 2024-09-04 09:32:05

也许你应该看看信号/槽机制。我认为这就是你实现你想要的目标所需要的。

将您的 onTransition 函数设置为槽而不是事件处理程序,并将其连接到按钮的 clicked 信号。

类 validateBoatTransition :公共 QtEventTransition
{
...

public slots:
    void onTransition();

...

}

在代码中的某个位置,将按钮连接到插槽:

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

每次单击按钮时,执行都会经过 onTransition 函数。

Maybe you should take a look to signals/slot mechanism. I think this is what you need to achieve what you want.

Make your onTransition function a slot instead of an event handler and connect it to the signal clicked of the button.

class validateBoatTransition : public QtEventTransition
{
...

public slots:
    void onTransition();

...

}

Somewhere in your code, connect the button to the slot:

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

Each time the button will be clicked the execution will go through the onTransition function.

伤痕我心 2024-09-04 09:32:05

我认为您正在尝试使用错误的类/机制来实现您的目标。如果我理解正确的话,你有一些 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);

通常我' d 使用信号来驱动状态机,除非某些转换显然是事件驱动的(例如 GUI 小部件上的一些 QEvent::Enter/QEvent::Leave 等)。

I think you're trying to use wrong classes/mechanisms to achieve your goals. If I understand you correctly, you have some GUI and after clicking some button you want to validate some stuff and if this validation is successful the state machine should change it's state. I'd write it this way:

Create some class to handle validation:

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

Then you connect your QPushButton::clicked() to BoatValidator::validate() and use BoatValidator::boatTransition() signal to drive the state machine:

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

Generally I'd use signal to drive state machine, unless some transitions are obviously event driven (for example some QEvent::Enter/QEvent::Leave on GUI widgets, etc.).

孤蝉 2024-09-04 09:32:05

我想做的是构建一个 Qt 状态机。问题是我无法触发我自己的转换(更不用说我自己的事件了)。给出的答案很好,但会导致代码混乱。如果我无法使用 QT 转换,为什么要使用 QT 状态机?
如果您创建一个新项目,上面的第一个问题就解决了。 QT Creator 非常烦人。
但现在我的解决方案可能对其他人有帮助。

首先我的状态:

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

然后将此增强的信息(当前)传递到我所在状态的插槽,我在其中选择调用执行工作的正确转换。如果需要,您可以将更多转换链接到它。

但最重要的是,你不需要重新编程过渡,我真的不喜欢这一点。

谢谢你的帮助,我一个人做不到。

What i wanted to do is build a Qt State Machine. The Problem was that i could not trigger my own Transitions (let alone with my own Events). The answers given are good but would lead to a messy code. Why should i use a QT State Machine if i could not use the QT Transitions?
The First Problem above is solved, if you create a new Project. QT Creater is very annoying.
But here now my solution , may it help others.

First my State:

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

Normal, but you see i added an Slot. This slot enables me to connect a bottom signal or a Widget Mouse Press Signal to it !
Like this:

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

all i needed to to is now fire a declared Event like this one :

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

when the slot was called:

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

The QT State Machine would now call all the Transitions , link with this state:

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

Whats so great that i dare to post?
Well first you can link a Qt SM to a widget where a mouse press event , or somthing else, is called and process the raw data to a an level you need later in your program. All you then need to do is, to emit the singal:

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

Then this enhenced information (current) is passed to the slot at my state, where i chose to call the correct transition that does the work. You could link more transitions to it, if you need it.

But most importend you dont need to reprogramm the Transition, a think i realy disliked.

Thank you for your help , i could not done it alone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文