借鉴Github上面的Qt开源项目说事儿之一(Qt for PC)

(续) 最近喜欢闲逛github,去上面看看关于Qt方面的一些开源资料和项目,看到好多优秀的Qt开源项目,特别在最新的移动开发方面的项目,比如Qt for iOS,Qt for Android等。
今天来说下Qt for PC,这个pc desktop项目很有借鉴意义,至少人家都是开源出来,不像国内某某等躲躲藏藏,呵呵,吐槽下国内IT行业
        下面我们说下这个开源项目的主要功能就是一个Android手机的pc管理文件管理工具,类似国内四分天下的手机助手,360,腾讯 百度91 豌豆荚等手机助手,不过功能肯定没有他们"强大" ,呵呵 你懂的,那四家使用Android调试工具  adb都是自己将源码修改后使用的,功能更加强大,在此不再表述。

        作者原话 Android File Manager using Android Debug Bridge and based on Qt  http://qtadb.wordpress.com    这个链接需要翻才可以查阅,翻得懂就好

        我们看下入口main函数

        

#include <QtGui/QApplication>
#include "./classes/application.h"
#include "./dialogs/mainwindow.h"
////////////////////////////////////////
#include <QtDebug>
#include <QFile>
#include <QTextStream>

void myMessageHandler(QtMsgType type, const char *msg)
{
    QStringList args = qApp->arguments();

    QString txt;
    switch (type) {
    case QtDebugMsg:
        txt = QString("Debug: %1").arg(msg);
        break;
    case QtWarningMsg:
        txt = QString("Warning: %1").arg(msg);
        break;
    case QtCriticalMsg:
        txt = QString("Critical: %1").arg(msg);
        break;
    case QtFatalMsg:
        txt = QString("Fatal: %1").arg(msg);
        abort();
    }
    if (args.contains("--debug"))
    {
        QFile outFile("debug.log");
        outFile.open(QIODevice::WriteOnly | QIODevice::Append);
        QTextStream ts(&outFile);

        txt.remove(QChar( 0xa ),Qt::CaseInsensitive);
        txt.remove(QChar( 0xd ),Qt::CaseInsensitive);

        ts << txt << endl;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication::setOrganizationName("Bracia");
    QCoreApplication::setApplicationName("QtADB");
    QCoreApplication::setApplicationVersion("0.8.1");
    QCoreApplication::setOrganizationDomain("http://qtadb.com");
    Application a(argc, argv);
    qInstallMsgHandler(myMessageHandler);
    a.loadTranslations(":/lang");
    a.loadTranslations(qApp->applicationDirPath());
    a.setQuitOnLastWindowClosed(true);
    qDebug()<<"app version: "<<QCoreApplication::applicationVersion();
#ifdef Q_WS_WIN
    switch(QSysInfo::windowsVersion())
    {
    case QSysInfo::WV_XP:qDebug()<<"system: Windows XP "<<QProcessEnvironment::systemEnvironment().value("PROCESSOR_ARCHITECTURE");
        break;
    case QSysInfo::WV_VISTA:qDebug()<<"system: Windows Vista "<<QProcessEnvironment::systemEnvironment().value("PROCESSOR_ARCHITECTURE");
        break;
    case QSysInfo::WV_WINDOWS7:qDebug()<<"system: Windows 7 "<<QProcessEnvironment::systemEnvironment().value("PROCESSOR_ARCHITECTURE");
        break;
    default:
        qDebug()<<"system: "<<QSysInfo::windowsVersion()<<" "<<QProcessEnvironment::systemEnvironment().value("PROCESSOR_ARCHITECTURE");
    }
#endif
//    qDebug()<<"system: "<<QSysInfo::windowsVersion();
//    qDebug()<<"bits: "<<QSysInfo::WordSize;
    QSettings settings;
    QString sdk;
    sdk = settings.value("sdkPath").toString();


    QString locale = QLocale::system().name().left(2);

    QString lang = settings.value("Language", locale).toString();
    bool langSet = false;

    if (!Application::availableLanguagesRes().contains(lang))
        lang = "en";
    foreach (QString avail, Application::availableLanguagesRes())
    {
        if (avail == lang)
        {
            langSet = true;
            Application::setLanguage(lang, "res");
        }
    }

    foreach (QString avail, Application::availableLanguagesDir())
    {
        if ((avail == lang) && (langSet == false))
        {
            Application::setLanguage(lang, "dir");
        }
    }

    bool sdkOk = false;
    do{
        QString tmp;
        if (sdk.isEmpty())
        {
            QDir checkSDK(QDir::currentPath());
            QFileInfoList list=checkSDK.entryInfoList();
            while(list.length()>0)
            {
                tmp = list.takeFirst().fileName();
                if (tmp.contains("adb"))
                {
                    sdk = QDir::currentPath();
                    sdk.append("/");
                    sdkOk=true;
                    break;
                }
            }
        }
        if (sdk.isEmpty())
        {
            sdk=QFileDialog::getExistingDirectory(NULL,QObject::tr("Choose path to dir with adb and aapt binaries"),"/");
            if (!sdk.isEmpty())
                sdk.append("/");
        }
        if (!sdk.isEmpty())
        {
            QDir checkSDK(sdk);
            QFileInfoList list=checkSDK.entryInfoList();
            while(list.length()>0)
            {
                tmp = list.takeFirst().fileName();
                if (tmp.contains("adb"))
                {
                    sdkOk=true;
                    break;
                }
            }
        }
        if (!sdkOk)
        {
            sdk.clear();
            QMessageBox *msgBox = new QMessageBox(QMessageBox::Critical, QObject::tr("error"), QObject::tr("there is no adb binary in here!"));
            QPushButton *choosePathMsg = msgBox->addButton(QObject::tr("Choose path"), QMessageBox::AcceptRole);
            QPushButton *closeMsg = msgBox->addButton(QObject::tr("Close"), QMessageBox::RejectRole);

            msgBox->exec();

            if (msgBox->clickedButton() == choosePathMsg)
            {
                continue;
            }
            else
            {
                break;
            }
            delete closeMsg;
            delete choosePathMsg;
            delete msgBox;
        }
        else break;
    }while(true);
    if (sdkOk){
        settings.setValue("sdkPath", sdk);
        QProcess proces;
//        adbd cannot run as root in production builds
        proces.setProcessChannelMode(QProcess::MergedChannels);
        proces.start("\"" + sdk + "\"adb version");
        proces.waitForFinished(-1);
        QString tmp = proces.readAll();
        qDebug()<<"adb version - "<<tmp;
        if (proces.exitCode() != 0)
        {
            qDebug()<<"adb error - "<<proces.errorString();
            QMessageBox *msgBox = new QMessageBox(QMessageBox::Critical, QObject::tr("error"), QObject::tr("It seems that adb is not working properly"), QMessageBox::Ok);
            msgBox->exec();
            delete msgBox;
            return 1;
        }
//        adbd cannot run as root in production builds
        proces.setProcessChannelMode(QProcess::MergedChannels);
        proces.start("\"" + sdk + "\"adb root");
        proces.waitForFinished(-1);
        tmp = proces.readAll();
        qDebug()<<"adb root - "<<tmp;

        if (tmp.contains("adbd cannot run as root in production builds") && !settings.value("disableProductionBuildsMessage",false).toBool())
        {
            QMessageBox *msgBox2 = new QMessageBox(QMessageBox::Critical, QObject::tr("error"),
                                                   QObject::tr("adbd cannot run as root in production builds so You can't do anything with /system partition. Run anyway?\n(press save to run QtADB and disable this message)"),
                                                   QMessageBox::Yes | QMessageBox::No | QMessageBox::Save);
            int button = msgBox2->exec();
            if ( button == QMessageBox::No)
            {
                delete msgBox2;
                return 0;
            }
            if ( button == QMessageBox::Save)
            {
                settings.setValue("disableProductionBuildsMessage",true);
            }
        }

        QStringList args = qApp->arguments();
        if (args.count() > 1)
        {
            if (args.at(1).endsWith(".apk"))
            {
                App *app = NULL;
                app = FileWidget::getAppInfo(args.at(1));
                appInfo *appInfoDialog = new appInfo(app);
                return appInfoDialog->exec();
            }
            if (args.at(1) == "-install")
            {
                QList<App> appList;
                App *app = NULL;
                for (int i = 2; i < args.count(); i++)
                {
                    if (args.at(i).endsWith(".apk"))
                    {
                        QString fileName = args.at(i);
                        app = FileWidget::getAppInfo(fileName);
                        if (app != NULL)
                            appList.append(*app);
                    }
                }
                appDialog *appDialogInstall = new appDialog(appList, appDialog::Install, appDialog::None);
                return appDialogInstall->exec();
            }
            else if (args.at(1) == "-logcat")
            {
                LogcatDialog *logcat = new LogcatDialog;
                return logcat->exec();
            }
        }
        MainWindow w;
        w.show();
        return a.exec();
    }
    else{
        return 0;
    }
}
简单说下该文件中所作的一些事情

myMessageHandler(QtMsgType type, const char *msg)是负责记录项目的调试日志

保存到一个log文件里面

main函数里面设置了应用名称等,再者检测了windows平台的版本,然后再读取了一些注册表信息,想找到用户是否安装了Android的sdk开发包,如果用户安装了Android SDk,则必然有Android调试工具adb,对于adb是否存在做了很多检测功能

另外还做了文件关联的功能,使用main函数的传参,进行apk的安装功能,对此需要对Adb这个工具做详细的了解,才能懂得这个项目意义所在

另外这个项目也是C++与QML混编的一个典型案例,有兴趣的Qter可以好好研究下,如果对现在的adb有不满,可以自行修改和编译adb源码

说到这里就奉上开源代码 Qt Android 管理工具客户端

希望大家可以从中学到不少Qt方面的东西和Android方面的东西

稍微我会继续说叨github上面的Qt开源项目

猜你喜欢

转载自blog.csdn.net/esonpo/article/details/38081607
PC: