在office word软件中,用户先改变字体颜色再改变段落格式或者反过来,最终的结果是一样的。Matlab软件也没有限制用户每个操作必须有先后。和office,matlab等不同,在工业自动化中需要的软件总是要有确定的流程。
在一些应用需求中,为了保证用户操作的便捷,需要将工作流程体现到GUI界面程序中。最近在这一块做了点工作,其核心思想介绍如下。
使用的开发框架是qt。把每个步骤需要执行的操作放到一个dock中,执行到哪一步,就显示哪一步的dock。还可以把需要一直显示的较多的内容也放到dock中,比如日志信息和传感器实时信息。每个步骤间通信使用信号槽来完成,因为每个dock都是一个QObject对象。使用一个dock控制流程进度,并可视化显示当前步骤和未执行和执行完的步骤。
在主界面类中定义如下类似的dock并添加到主界面中。
//设备1初始化dock,默认显示开
deviceInitDock = new DeviceInitDock();
addDockWidget(Qt::BottomDockWidgetArea,deviceInitDock);
//removeDockWidget(deviceInitDock);
//设备2初始化dock,默认关
deviceInit2Dock = new DeviceInit2Dock();
addDockWidget(Qt::BottomDockWidgetArea,deviceInit2Dock);
removeDockWidget(deviceInit2Dock);
//设备标定dock,默认关,
caliDock = new CaliDock();
addDockWidget(Qt::BottomDockWidgetArea,caliDock);
removeDockWidget(caliDock);
使用removeDockWidget和restoreDockWidget实现dock的隐藏和显示。Dock隐藏并不会销毁dock对象。
两dock间可以通过信号槽传递数据。
connect(deviceInitDock,SIGNAL(on_trackpos(float&,float&,float&)),deviceInit2Dock,SLOT(on_trackpos(float&,float&,float&)));
然后需要定义一个状态控制的类,该类继承自QObject,这个类也可以是dock,这样可以可视化当前状态,这也是本文采用的方法。
在每个流程dock中,都会有下一步和上一步(开始和结束的步骤另做处理)按钮,在按钮的槽函数中发射上一步或者下一步的消息,由状态控制类接收。
connect(deviceInitDock,SIGNAL(on_next_status(int)),statusDock,SLOT(on_next_status(int)));
connect(deviceInit2Dock,SIGNAL(on_next_status(int)),statusDock,SLOT(on_next_status(int)));
connect(deviceInit2Dock,SIGNAL(on_pre_status(int)),statusDock,SLOT(on_pre_status(int)));
connect(caliDock,SIGNAL(on_pre_status(int)),statusDock,SLOT(on_pre_status(int)));
deviceInit2Dock设备2初始化的下一个状态和上一个状态的消息和statusDock状态dock相连,传递的参数是当前步骤的代号,定义为一个枚举变量。
enum STATUS{
INIT = 1,
INIT2,
CALI,
CONNECT,
TARGET,
CURRENT,
SIM,
EXE
};
在StatusDock中,接收到上一步指令,根据传递的参数判断当前是什么状态,从而决定转到什么状态。
void StatusDock::on_pre_status(int cur)
{
if(cur == INIT2)
{
ui->pushButton_init->setStyleSheet("color: yellow");
ui->pushButton_init2->setStyleSheet("color: red");
emit init_command(); //通知主界面类显示或隐藏对应的dock
}
if(cur == CALI)
{
ui->pushButton_init2->setStyleSheet("color: yellow");
ui->pushButton_cali->setStyleSheet("color: red");
emit init2_command(); //通知主界面类显示或隐藏对应的dock
}
…
}
void StatusDock::on_next_status(int cur)
{
if(cur == INIT)
{
ui->pushButton_init->setStyleSheet("color: green");
ui->pushButton_init2->setStyleSheet("color: yellow");
emit init2_command(); //通知主界面类显示或隐藏对应的dock
}
else if(cur == INIT2)
{
ui->pushButton_init2->setStyleSheet("color: green");
ui->pushButton_cali->setStyleSheet("color: yellow");
emit cali_command(); //通知主界面类显示或隐藏对应的dock
}
…
}
这个函数通过发射一个消息通知主界面类显示或隐藏对应的dock。也会更改StatusDock中按钮的颜色。红色代表未执行到的步骤,绿色代表执行完成的步骤,黄色代表正在执行的步骤。