/*****************************************************************************
* Qt flash_eraseall nandwrite 进度条显示擦除、烧录
* 声明:
* 当我们在 Linux shell中执行nand擦除、烧入程序时,我们可以通过终端查看
* 过程,但是有时候我们可能希望能够有个界面,这样会更直观的提供当前的程序
* 的执行状态,于是个人写了这个Demo,目前暂时使用。
*
* 2015-10-7 雨 深圳 南山平山村 曾剑锋
****************************************************************************/ |\\\\\\\\-*- 目录 -*-///////
| 一、cat main.cpp
| 二、cat mainwindow.h
| 三、cat mainwindow.cpp
| 四、cat thread.h
| 五、cat thread.cpp
\\\\\\\\\\\\\\///////////// 一、cat main.cpp
#include "mainwindow.h"
#include <QApplication> int main(int argc, char *argv[])
{
QApplication a(argc, argv); /**
* 窗口最大化,不允许最小化
*/
MainWindow w;
w.setWindowFlags(w.windowFlags()& ~Qt::WindowMaximizeButtonHint& ~Qt::WindowMinimizeButtonHint);
w.showMaximized();
w.show(); return a.exec();
} 二、cat mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H #include <QMainWindow>
#include "thread.h" /**
* shell command:
* nandwrite -p /dev/mtd7 ubi.img
* ......
* Writing data to block 724 at offset 0x5a80000
* Writing data to block 725 at offset 0x5aa0000
* Writing data to block 726 at offset 0x5ac0000
* Writing data to block 727 at offset 0x5ae0000
* Writing data to block 728 at offset 0x5b00000
* Writing data to block 729 at offset 0x5b20000
* Writing data to block 730 at offset 0x5b40000
*
* 这个值要设置得相对大一点比较好,这样就不会出现比100%还大得情况
*/
#define NANDWRITEBLOCKCOUNTS 740 namespace Ui {
class MainWindow;
} class MainWindow : public QMainWindow
{
Q_OBJECT public:
explicit MainWindow(QWidget *parent = );
~MainWindow(); protected:
void moveEvent(QMoveEvent *);
void resizeEvent(QResizeEvent *);
void closeEvent(QCloseEvent *); public slots:
/**
* 与线程对应的三个信号处理函数
*/
void dealNandEraseMesg(QString string);
void dealNandWriteMesg(QString string);
void dealTitleMesg(QString string); private:
Ui::MainWindow *ui;
Thread *thread;
}; #endif // MAINWINDOW_H 三、cat mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QProcess>
#include <QDebug> MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this); /**
* 创建线程来处理nand的擦除、写入,主要是避免在MainWindow的UI线程中处理事务,
* 这样可以避免UI界面不能及时显示改变的数据界面,这在Android的开发中也会
* 遇到这种情况,类似的处理方式。
*/
thread = new Thread();
connect(thread, SIGNAL(nandEraserMesg(QString)), this, SLOT(dealNandEraseMesg(QString)));
connect(thread, SIGNAL(titleMesg(QString)), this, SLOT(dealTitleMesg(QString)));
connect(thread, SIGNAL(nandWriteMesg(QString)), this, SLOT(dealNandWriteMesg(QString)));
thread->start();
} void MainWindow::dealNandEraseMesg(QString string) {
ui->progressBar->setValue(string.toInt());
} void MainWindow::dealNandWriteMesg(QString string) {
int rate = string.toInt()*/NANDWRITEBLOCKCOUNTS;
/**
* 由于最后为了确保显示了100,我传了1000过来这个远大于NANDWRITEBLOCKCOUNTS的值
* 所以这里需要这样操作来避免显示大于100的值
*/
rate = rate >= ? : rate;
ui->progressBar->setValue(rate);
} void MainWindow::dealTitleMesg(QString string) {
ui->title->setText(string);
} MainWindow::~MainWindow()
{
delete ui;
} void MainWindow::moveEvent(QMoveEvent *)
{
/**
* 防止窗口被移动
*/
this->move(QPoint(,));
} void MainWindow::resizeEvent(QResizeEvent *)
{
this->showMaximized();
} void MainWindow::closeEvent(QCloseEvent *)
{
exit();
} 四、cat thread.h
#ifndef THREAD_H
#define THREAD_H #include <QThread>
#include <QProcess>
#include <QDebug> class Thread : public QThread
{
Q_OBJECT
public:
explicit Thread(QObject *parent = ); signals:
/**
* 数据处理过程中,需要用到的三个信号
*/
void titleMesg(QString string);
void nandEraserMesg(QString string);
void nandWriteMesg(QString string); public slots:
void run();
/**
* 判断字符串是不是数字组成的:
* 返回值:
* 0:表示是纯数字组成的;
* 1:表示不是纯数字组成的。
*/
int isDigitStr(QString src);
}; #endif // THREAD_H 五、cat thread.cpp
#include "thread.h"
#include <stdio.h>
#include <unistd.h>
#include <QByteArray>
#include <QStringList> Thread::Thread(QObject *parent) :
QThread(parent)
{
} /**
* 重写的run()方法
*/
void Thread::run()
{
QString readBuffer; /**
* 擦除的时候使用QProcess来处理
*/
QProcess process;
process.start("flash_eraseall /dev/mtd7");
process.waitForFinished(-); // will wait forever until finished /**
* 显示正在做的事
*/
emit titleMesg("erase rootfs...");
while ( !process.atEnd() ) { // 没有到数据末尾
if ( process.canReadLine() ) { // 有数据可读
readBuffer = process.readLine(); // 读取数据 /**
* Erasing 128 Kibyte @ ca40000 -- 81 % complet"
* Erasing 128 Kibyte" e560000 -- 92 % complete
* " asing 128 Kibyte @ e980000 -- 93 % complete
* Erasing 128 Kibyte @ eae0000 -- 94 % comp" te
* Erasing 128 Kibyt" @ f040000 -- 96 % complete
* Erasing 128 Kibyte @ f460000 -- 98 % complete "
*
* 以下代码主要是为了获取上面输出中的百分比数值
*/
// 正则表达式分割数据
QStringList currentLine = readBuffer.split(QRegExp("[\\s]+"));
if ( currentLine.length() > ) { // 我们需要第六个字段
// 第六个字段是否是由纯数字组成
if ( !isDigitStr( currentLine[]) ) {
// 将数据发送给UI线程去处理
emit nandEraserMesg(currentLine[]);
//qDebug() << readBuffer;
}
}
}
}
emit nandEraserMesg(QString()); // 擦除数据完毕 /**
* 1. shell命令行下执行 nandwrite -p /dev/mtd7 ubi.img 的输出:
* Writing data to block 47 at offset 0x5e0000
* Writing data to block 48 at offset 0x600000
* Writing data to block 49 at offset 0x620000
* Writing data to block 50 at offset 0x640000
* Writing data to block 51 at offset 0x660000
* 2. 在编码测试过程中发现使用QProcess无法获取到nandwrite执行过程中的数据,
* 仅仅在处理完毕的时候才会收到数据,所以处理效果不好;
* 3. 所以改用popen来做这件事,但是popen也仅仅是比QProcess好那么一点,每次
* 都是以12%的梯度增长,虽然还是没有像shell中运行的效果,但目前勉强还
* 是能用,所以这里也就暂时这么做;
* 4. 目前没找到更好的办法在解决这个事情。
*/
char buff[];
FILE *fp = popen("nandwrite -p /dev/mtd7 ubi.img", "r"); int count = ;
emit titleMesg("update rootfs...");
while (!feof(fp)) {
fgets(buff, , fp );
emit nandWriteMesg(QString::number(count++));
}
pclose(fp);
// 这里仅仅是为了保证processor bar一定显示100%才这么做的,没其他的意思
emit nandWriteMesg(""); // 显示更新完毕
emit titleMesg("rootfs update over.");
} int Thread::isDigitStr(QString src)
{
//QString 转换为 char*
QByteArray ba = src.toLatin1();
const char *s = ba.data(); /**
* 字符的二进制值是否在'0'、'9'之间
*/
while(*s && *s>='' && *s<='') s++; if (*s) { //不是纯数字
return -;
} else { //纯数字
return ;
}
}