经过几次尝试后,发现用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";
- }