前言:嵌入式项目需要升级功能,升级范围有应用升级,系统升级,外设固件升级,升级包的下载等,每一项升级都包含以下流程,检测安装包,提示用户是否升级,升级过程中提供进度,提示用户升级完成。
经过几次尝试后,发现用if多个分支已不能很好的管理这么多选项了,经同事提示考虑使用状态机。的确是个稳妥的方法。但经试验后发现有一个问题,就是 安装包复制完成后 ,本想驱动状态机进入 “提示用户已完成的UI”,但就像程序睡眠了一样,卡住了,经kill -9 pid杀掉后,之后每次升级都不会卡了,联想到startapp.sh中App退出后有一个sync操作。因此在App中每次 FileCopy如果都 强行加入sync,神奇的解决了问题,有大侠知道原因的请指教
简化的代码如下:
mainwindow.h
-
#ifndef MAINWINDOW_H
-
#define MAINWINDOW_H
-
-
#include <QWidget>
-
#include <QState>
-
#include <QStateMachine>
-
-
#include <QAbstractTransition>
-
#define STATE_WRITING 0
-
#define STATE_WRITE_FINISH 1
-
-
namespace Ui {
-
class MainWindow;
-
}
-
-
-
struct BootStateEvent : public QEvent
-
{
-
BootStateEvent(const int &val) :
-
QEvent(QEvent::Type(QEvent::User+100)),
-
value(val) {
-
-
}
-
int value;
-
};
-
class BootStateTransition : public QAbstractTransition
-
{
-
public:
-
BootStateTransition(const int &value)
-
: m_value(value) {}
-
protected:
-
bool eventTest(QEvent *e)
-
{
-
if (e->type() != QEvent::Type(QEvent::User+100))// BootStateEvent
-
return false;
-
BootStateEvent *se = static_cast<BootStateEvent*>(e);
-
return (m_value == se->value);
-
}
-
-
void onTransition(QEvent *) {}
-
private:
-
int m_value;
-
-
};
-
-
class MainWindow : public QWidget
-
{
-
Q_OBJECT
-
-
public:
-
explicit MainWindow(QWidget *parent = 0);
-
~MainWindow();
-
-
private slots:
-
void slotWritingFileOnEnter();
-
void slotShowFinishOnEnter();
-
private:
-
Ui::MainWindow *ui;
-
void doCopyFile();//do file copy
-
void doSync();
-
void initMachine();
-
QState *writingFile ;
-
QState *showFinish ;
-
QStateMachine *machine ;
-
};
-
-
#endif // MAINWINDOW_H
mainwindow.cpp
-
#include "mainwindow.h"
-
#include "ui_mainwindow.h"
-
#include <QDebug>
-
#include <QProcess>
-
MainWindow::MainWindow(QWidget *parent) :
-
QWidget(parent),
-
ui(new Ui::MainWindow)
-
{
-
ui->setupUi(this);
-
initMachine();
-
machine->start();
-
-
}
-
-
MainWindow::~MainWindow()
-
{
-
delete ui;
-
}
-
void MainWindow::slotWritingFileOnEnter(){
-
doCopyFile();
-
doSync();
-
machine->postEvent(new BootStateEvent(STATE_WRITE_FINISH));//这一句之前加doSync(),否则转入不到s lotShowFinishOnEnter
-
-
}
-
-
void MainWindow::doCopyFile()
-
{
-
qDebug()<<"FileCopy...";
-
qDebug()<<"FileCopy finished";
-
-
}
-
-
void MainWindow::doSync()
-
{
-
qDebug()<<"doSync...";
-
QProcess p;
-
-
QEventLoop loop;
-
QObject::connect(&p,SIGNAL(finished(int)),&loop,SLOT(quit()));
-
-
QString programPath = "/sbin/sync";
-
QStringList args;
-
p.start(programPath,args);
-
p.waitForFinished( -1 );
-
}
-
-
void MainWindow::initMachine()
-
{
-
writingFile = new QState();
-
showFinish = new QState();
-
machine = new QStateMachine();
-
-
-
machine->addState( writingFile );
-
machine->addState( showFinish );
-
machine->setInitialState( writingFile );
-
-
BootStateTransition *writingFinishTran = new BootStateTransition(STATE_WRITE_FINISH);
-
-
writingFinishTran->setTargetState( showFinish );
-
writingFile->addTransition( writingFinishTran );
-
-
connect(writingFile,SIGNAL(entered()),this,SLOT(slotWritingFileOnEnter()));
-
connect(showFinish,SIGNAL(entered()),this,SLOT(slotShowFinishOnEnter()));
-
-
}
-
-
void MainWindow::slotShowFinishOnEnter(){
-
//show finish info
-
qDebug()<<"slotShowFinishOnEnter";
-
}
阅读(4665) | 评论(0) | 转发(0) |