草庐IT

c++ - Qt 状态机 : How to associate a single transition with multiple states

coder 2024-02-22 原文

问题

我目前正在开发一个使用 Qt 状态机框架的应用程序,我的目标是将单个转换与多个源状态相关联。这样做的理由是导致转换的信号独立于源状态,因此我认为最好有一个而不是多个转换(每个源状态一个)。我在通过 Qt 实现上述目标时遇到了问题。下面使用测试状态机演示了详细信息。 (下面提到的是一个假设的状态机,但我也可以为这种用例提供​​一些真实世界的例子)。请提出一些有效的方法来实现上述目标。

问题所在的代码片段

m_s1.addTransition(&m_Trans); // Adding transition to state S1
m_s2.addTransition(&m_Trans); // Adding the same transition to state S2
                              // As per Qt docs, it seems the ownership of thr transition will be transferred to s2 which is what is causing the problem.

CState.hpp

class CState: public QState
{

public:

    /** Constructor */
    CState(std::string a_pStateName)
       :QState(nullptr),
        m_pStateName(a_pStateName)
    {

    }

    /** Overriding on entry */
    virtual void onEntry(QEvent *a_pEvent) Q_DECL_OVERRIDE
    {
        (void) a_pEvent;
        printf("State entry %s\n",m_pStateName.c_str());
    }

    ~CState() {}
     CState() {}
private:
    std::string  m_pStateName;
};

CTestMachine.hpp

class CTestStateMachine: public QObject
{
    Q_OBJECT

public:
    CTestStateMachine();
    ~CTestStateMachine() {};

private:
    QSignalTransition       m_Trans;
    CState                  m_s1;
    CState                  m_s2;
    CState                  m_s3;
    QStateMachine           m_TestMachine;
    QTimer                  m_Timer;

signals:
    void SourceIndependentSignal();

public slots:
    void TimetoInvokeTrans();


};

CTestMachine.cpp

#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;

#include <QObject>
#include <QCoreApplication>
#include <QStateMachine>
#include <QState>
#include <QSignalTransition>
#include <QTimer>

#include "CState.hpp"
#include "CTestStateMachine.hpp"

void CTestStateMachine::TimetoInvokeTrans()
{
    printf("Emitting source independent signal\n");
    emit SourceIndependentSignal();
}

CTestStateMachine::CTestStateMachine():
    m_Trans(this, SIGNAL(SourceIndependentSignal())),
    m_s1("s1"),
    m_s2("s2"),
    m_s3("s3")
{
   /* Setup state machine */
   m_Trans.setTargetState(&m_s3);
   m_s1.addTransition(&m_Trans);
   m_s2.addTransition(&m_Trans);
   m_TestMachine.addState(&m_s1);
   m_TestMachine.addState(&m_s2);
   m_TestMachine.addState(&m_s3);
   m_TestMachine.setInitialState(&m_s1);
   m_TestMachine.start();
   printf("Started state machine\n");

   /* Trigger timer to make transitions */
   connect(&m_Timer, SIGNAL(timeout()), this, SLOT(TimetoInvokeTrans()));
   m_Timer.start(1000);
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    CTestStateMachine TestMachine;
    return a.exec();
}

最佳答案

您可以在进入状态时移动转换。

connect(m_state, &QState::entered, [m_state, m_tr]() -> void { m_state->addTransition(m_tr); });

或者只是让父状态保持转换并将转换类型设置为内部。

QState *s = new QState(m_stateMachine);
QState *s1 = new QState(s);
QState *s2 = new QState(s);
QState *s3 = new QState(s);
QSignalTransition *sTr = new QSignalTransition(sender, SIGNAL(foobar), s);
sTr->setTargetState(s3);
sTr->setTransitionType(QAbstractTransition::InternalTransition);

关于c++ - Qt 状态机 : How to associate a single transition with multiple states,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33201993/

有关c++ - Qt 状态机 : How to associate a single transition with multiple states的更多相关文章

  1. ruby - 在 Ruby 程序执行时阻止 Windows 7 PC 进入休眠状态 - 2

    我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0

  2. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  3. ruby-on-rails - 跳过状态机方法的所有验证 - 2

    当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested

  4. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  5. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. Qt Designer的简单使用 - 2

    在前面两节的例子中,主界面窗口的尺寸和标签控件显示的矩形区域等,都是用C++代码编写的。窗口和控件的尺寸都是预估的,控件如果多起来,那就不好估计每个控件合适的位置和大小了。用C++代码编写图形界面的问题就是不直观,因此Qt项目开发了专门的可视化图形界面编辑器——QtDesigner(Qt设计师)。通过QtDesigner就可以很方便地创建图形界面文件*.ui,然后将ui文件应用到源代码里面,做到“所见即所得”,大大方便了图形界面的设计。本节就演示一下QtDesigner的简单使用,学习拖拽控件和设置控件属性,并将ui文件应用到Qt程序代码里。使用QtDesigner设计界面在开始菜单中找到「Q

  8. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  9. ruby-on-rails - 为模型创建状态属性 - 2

    我想为我的Task模型创建一个status属性,该属性将按以下顺序指示它在三部分进度中的位置:打开=>进行中=>完成。它的工作方式类似于亚马逊包裹的交付方式:已订购=>已发货=>已交付。我想知道设置此属性的最佳方法是什么。我可能是错的,但创建三个独立的bool属性似乎有点多余。实现此目标的最佳方法是什么? 最佳答案 Rails4有一个内置的enummacro.它使用单个整数列并映射到键列表。classOrderenumstatus:[:ordered,:shipped,:delivered]end状态映射如下:{ordered:0,

  10. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

随机推荐