diff --git a/QtAdb/QtAdb.pro b/QtAdb/QtAdb.pro index d6109d9..43f09ce 100644 --- a/QtAdb/QtAdb.pro +++ b/QtAdb/QtAdb.pro @@ -1,4 +1,5 @@ QT += core gui +QT += serialport greaterThan(QT_MAJOR_VERSION, 4): QT += widgets CONFIG += c++11 @@ -38,6 +39,7 @@ SOURCES += \ textexplainer.cpp \ threads/adbthread.cpp \ threads/thread_createpage.cpp \ + usb_listener.cpp \ welcomepage.cpp HEADERS += \ @@ -70,6 +72,7 @@ HEADERS += \ textexplainer.h \ threads/adbthread.h \ threads/thread_createpage.h \ + usb_listener.h \ welcomepage.h FORMS += \ diff --git a/QtAdb/about.cpp b/QtAdb/about.cpp index e83e06c..0fe964d 100644 --- a/QtAdb/about.cpp +++ b/QtAdb/about.cpp @@ -5,9 +5,8 @@ about::about(QWidget *parent) : basePage(parent), ui(new Ui::about) { - ui->setupUi(this); - self_castrate(); + ui->setupUi(this); QGraphicsDropShadowEffect *shadowEffect_btn_website = new QGraphicsDropShadowEffect(this); shadowEffect_btn_website->setOffset(0,0); @@ -58,6 +57,9 @@ about::about(QWidget *parent) : ui->btn_money->hide(); ui->btn_money_3->hide(); ui->btn_money_4->hide(); + + this->setStyleSheet("QToolTip{border:1px solid #BDBDBD; background-color: #ffffff; color:rgba(117, 117, 117, 0.9);font-family: MiSans Medium; font-size:12px;border-radius:4px;}"); + } about::~about() diff --git a/QtAdb/about.ui b/QtAdb/about.ui index f3159dd..ea86de2 100644 --- a/QtAdb/about.ui +++ b/QtAdb/about.ui @@ -112,7 +112,7 @@ QPushButton:pressed{background-color:rgba(255,255,255,0.6);} - 测试版本:beta-v0.5 + 测试版本:beta-v0.6 diff --git a/QtAdb/animationwidget.cpp b/QtAdb/animationwidget.cpp index f1a1f31..1ae0628 100644 --- a/QtAdb/animationwidget.cpp +++ b/QtAdb/animationwidget.cpp @@ -15,14 +15,14 @@ void animationWidget::playLoadAnimation() qDebug() << "wgtHeight = " << wgtHeight; if(parent->width() <= 600) { - animation->setEndValue(QRect(301, 117, 600,wgtHeight)); + animation->setEndValue(QRect(301, 117 - 6, 600,wgtHeight)); } else { - animation->setEndValue(QRect(301, 117, parent->width(),wgtHeight)); + animation->setEndValue(QRect(301, 117 - 6, parent->width(),wgtHeight)); } //animation->setStartValue(QPoint(301 + 50,117)); - animation->setStartValue(QRect(301 + 50, 117, parent->width()-50,wgtHeight)); + animation->setStartValue(QRect(301 + 50, 117 - 6, parent->width()-50,wgtHeight)); animation->setEasingCurve(QEasingCurve::OutQuart); @@ -38,14 +38,14 @@ void animationWidget::playLoadAnimation(int h) //qDebug() << "wgtHeight = " << wgtHeight; if(parent->width() <= 600) { - animation->setEndValue(QRect(301, 117, 600,h)); + animation->setEndValue(QRect(301, 117 - 6, 600,h)); } else { - animation->setEndValue(QRect(301, 117, parent->width(),h)); + animation->setEndValue(QRect(301, 117 - 6, parent->width(),h)); } //animation->setStartValue(QPoint(301 + 50,117)); - animation->setStartValue(QRect(301 + 50, 117, parent->width()-50,h)); + animation->setStartValue(QRect(301 + 50, 117 - 6, parent->width()-50,h)); animation->setEasingCurve(QEasingCurve::OutQuart); diff --git a/QtAdb/mainwindow.cpp b/QtAdb/mainwindow.cpp index 3fd06fa..e3986aa 100644 --- a/QtAdb/mainwindow.cpp +++ b/QtAdb/mainwindow.cpp @@ -36,11 +36,22 @@ MainWindow::MainWindow(QWidget *parent) addIndexItems(); //设置左侧目录 setStyles(); //设置样式 - /*初始化对象*/ process = new adbProcess(); explainer = new textExplainer(); maker = new pageMaker(); + listener = new usb_listener(); + + //connect(listener, SIGNAL(DevicePlugIn()),this,SLOT(DevicePlugIn())); + //connect(listener, SIGNAL(DevicePlugOut()),this,SLOT(DevicePlugOut())); + connect(listener, SIGNAL(DeviceChanged()),this,SLOT(refreshDevListLater())); + connect(this, SIGNAL(adbDeviceChanged()),this,SLOT(DeviceChanged())); + qApp->installNativeEventFilter(listener); + + //listener->EmitMySignal(); + this->setAttribute(Qt::WA_NativeWindow); + + /*启动监听*/ /*启动ADB,将延长页面创建时间,在此期间显示启动界面,显示了个勾八*/ process->run("adb server"); @@ -75,9 +86,97 @@ void MainWindow::initEnvironmentPATH() //方法:设置环境变 void MainWindow::refreshDevList() //方法:刷新设备列表 { - ui->comboBox->clear(); + //ui->comboBox->clear(); + /*DEBUG*/ + bool changed = false; + qDebug() << "******************一次调用*********************"; + qDebug() << "refreshDevList devList is empty? " << devList.isEmpty() << QTime::currentTime(); + qDebug() << "devList.size()" << devList.size(); + + for(int i = 0; i < devList.size();i++) + { + qDebug() << "devList[" << i << "] is :" << devList[i].addr; + } + + /*DEBUG_END*/ + qDebug() << "shit 0"; + bool devList_is_empty = devList.isEmpty(); + + QList tmpList; + + /*给tmpList赋值*/ + if(!devList_is_empty) + { + for(int i = 0; i < devList.size();i++) + { + qDebug() << "shit 3.1"; + device dev; + dev.device_debug = devList[i].device_debug; + dev.device_product = devList[i].device_product; + dev.addr = devList[i].addr; + dev.model = devList[i].model; + dev.state = devList[i].state; + dev.transport_id = devList[i].transport_id; + tmpList.append(dev); + } + } + qDebug() << "tmpList.size()" << tmpList.size(); + + //ui->comboBox->clear(); devList.clear(); //清空设备列表 devList = explainer->getDevList_windows(process->run("adb devices -l")); //重新赋值 + qDebug() << "devList after explain:" << devList.isEmpty(); + + /* + qDebug() << "shit 1"; + for(int i = 0; i < tmpList.size();i++) + { + qDebug() << "shit 2"; + qDebug() << "tmpList[" << i << "] is :" << devList[i].addr; + } + for(int i = 0; i < devList.size();i++) + { + qDebug() << "shit 3"; + qDebug() << "devList new[" << i << "] is :" << devList[i].addr; + } + qDebug() << "shit finish";*/ + + + /*判断列表内容是否变化,若变化则发送 adbDeviceChanged 信号*/ + if(!devList_is_empty) + { + if(devList.size() == tmpList.size()) + { + for(int i = 0; i < devList.size() && i < tmpList.size() ; i++) + { + if(devList[i].addr != tmpList[i].addr) + { + emit adbDeviceChanged(); + changed = true; + break; + } + } + } + else + { + emit adbDeviceChanged(); + changed = true; + } + } + else if(!devList.isEmpty() && tmpList.isEmpty()) + { + emit adbDeviceChanged(); + changed = true; + } + else if(devList.isEmpty() && !tmpList.isEmpty()) + { + emit adbDeviceChanged(); + changed = true; + } + else + { + qDebug() << "else:" << devList.isEmpty() << tmpList.isEmpty() << devList_is_empty; + } QList off; //未响应设备索引 @@ -89,6 +188,7 @@ void MainWindow::refreshDevList() //方法:刷新设备列 { QString devItem = devList[i].state + " " + explainer->get_words_after(devList[i].model, ":") + " " + devList[i].addr; l.append(devItem); + qDebug() << "l[" << i << "] = " << l[i]; if(devList[i].state == "[未响应]") { off.append(i); @@ -99,7 +199,21 @@ void MainWindow::refreshDevList() //方法:刷新设备列 } } - ui->comboBox->addItems(l); + if(changed) + { + qDebug() <<"changed so clear"; + ui->comboBox->clear(); + ui->comboBox->addItems(l); + } + + if(!liangYi) + { + qDebug() <<"liangYi so clear"; + ui->comboBox->clear(); + ui->comboBox->addItems(l); + } + + liangYi = false; for(int i = 0; i < off.count();i++) { @@ -115,6 +229,10 @@ void MainWindow::refreshDevList() //方法:刷新设备列 { current_device = 0; } + + liangYi = false; + + qDebug() << "******************一次调用结束*********************"; } void MainWindow::on_refreshButton_clicked() //槽:按下刷新按钮 @@ -130,7 +248,6 @@ void MainWindow::on_refreshButton_clicked() //槽:按下刷新按钮 }*/ initBasePage(6); - qDebug() <<"8"; } void MainWindow::setCurrentDevice(int index) //槽:改变所选设备 @@ -540,3 +657,60 @@ void MainWindow::on_cmdBtn_clicked() batProcess.start(batPath); batProcess.waitForFinished(); } + +void MainWindow::DevicePlugIn() +{ + qDebug() << "DevicePlugIn"; +} + +void MainWindow::DevicePlugOut() +{ + qDebug() << "DevicePlugout"; +} + +void MainWindow::DeviceChanged() +{ + if(firstBoot == true) + { + firstBoot = false; + } + else + { + QMessageBox::StandardButton result=QMessageBox::warning(NULL, "检测到USB热插拔","您可能插入或拔出了一台ADB设备\n" + "将对设备列表进行刷新\n" + "(⚠️这会中断当前正在执行的任务)"); + + //msgBox->setStyleSheet("background-color:rgba(255,255,255,1);border:0px; border-radius:0px;"); + //QMessageBox::StandardButton result=QMessageBox::warning(this, "Title","text"); + //qDebug() << "result =" << result; + if(result) + { + //这里要delete adbprocess + on_refreshButton_clicked(); + } + else + { + + } + //qDebug() << "DeviceChanged"; + } +} + +void MainWindow::slot_refreshDevList() +{ + //qDebug() << "slot_refreshDevList"; + liangYi = true; + refreshDevList(); +} + + +void MainWindow::refreshDevListLater() +{ + + //qDebug() << ">>>>>>>>>>>>>>>>>>>>>>refreshDevListLater"; + QTimer *timer = new QTimer(); + connect(timer, SIGNAL(timeout()), this, SLOT(slot_refreshDevList())); + timer->setSingleShot(true); + timer->start(1000); + //timer->deleteLater(); +} diff --git a/QtAdb/mainwindow.h b/QtAdb/mainwindow.h index 761dcc0..96fb1bf 100644 --- a/QtAdb/mainwindow.h +++ b/QtAdb/mainwindow.h @@ -1,5 +1,9 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +/* +#define 布尔 bool +#define 为 = +#define 真 true*/ #include #include @@ -14,8 +18,8 @@ #include "indexlistitem.h" #include "basepage.h" #include "pagemaker.h" -#include "threads/thread_createpage.h" #include "about.h" +#include "usb_listener.h" #include #include @@ -33,6 +37,7 @@ class MainWindow : public QMainWindow { Q_OBJECT signals: + void adbDeviceChanged(); public: MainWindow(QWidget *parent = nullptr); @@ -49,7 +54,6 @@ class MainWindow : public QMainWindow QLineEdit * le_port; QLineEdit * le_code; - int current_device; QList devList; indexListItem listItems[10]; @@ -81,12 +85,28 @@ private slots: void addIndexItems(); void setStyles(); - bool taiChi = true; + bool taiChi = true; //界面锁定定时器 + bool liangYi = false; //判断刷新按钮槽函数是被谁调用:false:click()调用 ; true: 自行connect() + bool bagua = true; //忘了是干啥的了 + + //布尔 太极 为 真; + + + bool firstBoot = true; QTimer *taiChiTimer; + QTimer *baguaTimer; basePage * currentPage; animationWidget * tmpPage; about * WCMPage2; + usb_listener *listener; + +public slots: + void DevicePlugIn(); + void DevicePlugOut(); + void DeviceChanged(); + void slot_refreshDevList(); + void refreshDevListLater(); }; #endif // MAINWINDOW_H diff --git a/QtAdb/sonPages/apps/sp_installer.cpp b/QtAdb/sonPages/apps/sp_installer.cpp index b6abe55..f29260b 100644 --- a/QtAdb/sonPages/apps/sp_installer.cpp +++ b/QtAdb/sonPages/apps/sp_installer.cpp @@ -21,6 +21,7 @@ sp_installer::sp_installer(QWidget *parent) : QGraphicsDropShadowEffect *shadowEffect_back_to_basePage = new QGraphicsDropShadowEffect(this); QGraphicsDropShadowEffect *shadowEffect_refreshBtn = new QGraphicsDropShadowEffect(this); QGraphicsDropShadowEffect *shadowEffect_selectBtn = new QGraphicsDropShadowEffect(this); + QGraphicsDropShadowEffect *shadowEffect_tips = new QGraphicsDropShadowEffect(this); shadowEffect_runBtn->setOffset(0,0); shadowEffect_runBtn->setColor(Qt::gray); @@ -42,11 +43,16 @@ sp_installer::sp_installer(QWidget *parent) : shadowEffect_selectBtn->setColor(Qt::gray); shadowEffect_selectBtn->setBlurRadius(5); + shadowEffect_tips->setOffset(0,0); + shadowEffect_tips->setColor(Qt::green); + shadowEffect_tips->setBlurRadius(5); + ui->back_to_basePage->setGraphicsEffect(shadowEffect_back_to_basePage); ui->runBtn->setGraphicsEffect(shadowEffect_runBtn); ui->showOutputBtn->setGraphicsEffect(shadowEffect_showOutputBtn); ui->refreshBtn->setGraphicsEffect(shadowEffect_refreshBtn); ui->selectBtn->setGraphicsEffect(shadowEffect_selectBtn); + ui->tips->setGraphicsEffect(shadowEffect_tips); /* QGraphicsDropShadowEffect *shadowEffect_widget = new QGraphicsDropShadowEffect(); diff --git a/QtAdb/sonPages/apps/sp_installer.ui b/QtAdb/sonPages/apps/sp_installer.ui index f241e2d..c74e4c6 100644 --- a/QtAdb/sonPages/apps/sp_installer.ui +++ b/QtAdb/sonPages/apps/sp_installer.ui @@ -203,6 +203,37 @@ QProgressBar:chunk{ + + + + + 0 + 30 + + + + + 16777215 + 30 + + + + + MiSans Medium + 12 + + + + background-color:rgba(255,255,255,0.6);border-radius:4px;border:0px; + + + 执行时切勿插拔设备 + + + Qt::AlignCenter + + + diff --git a/QtAdb/sonPages/recovery/sp_recovery.cpp b/QtAdb/sonPages/recovery/sp_recovery.cpp index 14e6268..13b37fc 100644 --- a/QtAdb/sonPages/recovery/sp_recovery.cpp +++ b/QtAdb/sonPages/recovery/sp_recovery.cpp @@ -89,7 +89,7 @@ void sp_recovery::on_runBtn_clicked() { //qDebug() << "enter runBtn slot"; ui->progressBar->setVisible(true); - ui->output->setText("正在刷入,请在设备端查看进度"); + ui->output->setText("正在刷入,请在设备端查看进度,切勿插拔设备"); QString command; @@ -110,21 +110,6 @@ void sp_recovery::on_runBtn_clicked() this->setDisabled(true); - /* - pageListItemStruct *productModel = initStruct(devInfo); - productModel->item->setText_title("设备型号 | DeviceModel"); - productModel->item->setPic(":/ico/image/ico/profile-line.svg"); - productModel->thread->initThread("adb shell getprop ro.product.model", dev); - QEventLoop::connect(productModel->thread,SIGNAL(signal_output(QString)),productModel->item,SLOT(slot_setText_profile(QString))); - //QEventLoop::connect(devInfo,SIGNAL(animationEnd()),productModel->item,SLOT(slot_setStyles())); - productModel->thread->start(); - devInfo->addItemsToList(productModel->item); - //qDebug() << "item is in thread" << productModel->item->thread();*/ - - //qDebug() << "command: " << command; - //qDebug() << "running"; - //process->run_contains_empty(command, dev); - zipPath.clear(); labelDisplay.clear(); diff --git a/QtAdb/usb_listener.cpp b/QtAdb/usb_listener.cpp new file mode 100644 index 0000000..121666b --- /dev/null +++ b/QtAdb/usb_listener.cpp @@ -0,0 +1,91 @@ +#include "usb_listener.h" +#include +#include + +#include + +bool usb_listener::nativeEventFilter(const QByteArray &eventType, void *message, long long *result) +{ + MSG* msg = reinterpret_cast(message); + //qDebug() << "msg = " << msg; + unsigned int msgType = msg->message; + //qDebug() << "msgType = " << msgType; + //qDebug() << WM_DEVICECHANGE; + if(msgType == WM_DEVICECHANGE) { + emit DeviceChangeCbk(); + + //qDebug() << "msgType = " << msgType; + //qDebug() << "WM_DEVICECHANGE = " << WM_DEVICECHANGE; + qDebug() << "wParam = " << msg->wParam; + //qDebug() << "lParam = " << msg->lParam; + //qDebug() << "WM_DEVICECHANGE = " << WM_DEVICECHANGE; + qDebug() << "DBT_DEVICEARRIVAL = " << DBT_DEVICEARRIVAL; + qDebug() << "DBT_DEVICEREMOVECOMPLETE = " << DBT_DEVICEREMOVECOMPLETE; +/* + PDEV_BROADCAST_HDR lpdb = PDEV_BROADCAST_HDR(msg->lParam); + qDebug() << "lpdb = " << msg->lParam; + PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb); + qDebug() << "pDevInf = " << pDevInf; + qDebug() << "pDevInf->dbcc_name = " << pDevInf->dbcc_name; + QString device_name = "插入设备(name):"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8(); + + qDebug() << device_name;*/ + //bool dbg = msg->lParam == WM_DEVICECHANGE; + //qDebug() << "msg->lParam == WM_DEVICECHANGE = " <lParam type = " << typeid(msg->lParam).name(); + //if(msg->wParam == DBT_DEVICEARRIVAL) + emit DeviceChanged(); + //if(msg->lParam == WM_DEVICECHANGE) + if(msg->wParam == DBT_DEVICEARRIVAL) + { + qDebug("usb in"); + emit DevicePlugIn(); //触发信号 + } + if(msg->wParam == DBT_DEVICEREMOVECOMPLETE) + { + qDebug("usb out"); + emit DevicePlugOut(); //触发信号 + } + } + + return QWidget::nativeEvent(eventType, message, result); +} + +void usb_listener::EmitMySignal() +{ + emit DevicePlugIn(); +} +/* +bool usb_listener::nativeEvent(const QByteArray &eventType, void *message, long long *result) +{ + MSG* msg = reinterpret_cast(message);//第一层解算 + qDebug() << "msg = " << msg; + UINT msgType = msg->message; + if(msgType==WM_DEVICECHANGE) + { + PDEV_BROADCAST_HDR lpdb = PDEV_BROADCAST_HDR(msg->lParam);//第二层解算 + switch (msg->wParam) { + case DBT_DEVICEARRIVAL: + if(lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) + { + PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb); + QString device_name = "插入设备(name):"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8(); + + qDebug()<< device_name; + } + break; + case DBT_DEVICEREMOVECOMPLETE: + if(lpdb->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) + { + PDEV_BROADCAST_DEVICEINTERFACE pDevInf = PDEV_BROADCAST_DEVICEINTERFACE(lpdb); + QString device_name = "移除设备(name):"+QString::fromWCharArray(pDevInf->dbcc_name,int(pDevInf->dbcc_size)).toUtf8(); + + qDebug()<< device_name; + } + break; + } + } + return false; +} +*/ diff --git a/QtAdb/usb_listener.h b/QtAdb/usb_listener.h new file mode 100644 index 0000000..7b287a9 --- /dev/null +++ b/QtAdb/usb_listener.h @@ -0,0 +1,27 @@ +#ifndef USB_LISTENER_H +#define USB_LISTENER_H + +#include +#include +#include +#include + +class usb_listener:public QWidget, public QAbstractNativeEventFilter +{ + Q_OBJECT +public: + + void EmitMySignal(); + +protected: + bool nativeEventFilter(const QByteArray &eventType, void *message, long long *result); + //bool nativeEvent(const QByteArray &eventType, void *message, long long *result); + +signals: + void DeviceChangeCbk(); + void DeviceChanged(); + void DevicePlugIn(); + void DevicePlugOut(); +}; + +#endif // USB_LISTENER_H diff --git a/README.md b/README.md index 2566a25..778a09d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ QtAdb 是一个基于 [Qt](https://www.qt.io/) 的 Android 工具集合。 -> QtAdb 仍处于开发中,暂未正式发布,但您仍可以下载体验版本。 +> ~~QtAdb 仍处于开发中,暂未正式发布,但您仍可以下载体验版本。~~ +> +> QtAdb 已于 2022/8/17 发布第一个正式可用的版本 beta-v0.6 ,将进入功能添加与细节优化阶段。 ## 🧑‍💻开发目的 @@ -24,7 +26,7 @@ Android 系统的可玩性在 adb 的加成下变得更加的丰富,由此涌 - ~~不仅支持 adb 命令,还集成了一定数量的 **Fastboot** 命令,方便刷机等操作。~~*暂未实现* - 提供命令模板,使用者可直接复制命令并自行执行。 -- 支持多种状态显示及使用:开机、Recovery、Fastboot 及 adb sideload. +- 支持多种状态显示及使用:开机、Recovery、~~Fastboot~~及 adb sideload. ## 🛠️功能 @@ -89,9 +91,10 @@ Android 系统的可玩性在 adb 的加成下变得更加的丰富,由此涌 - 跨平台 - 完善网站 - 文件管理(~~都连上电脑了,为什么不直接用电脑的文件管理~~) -- 设备插拔检测 +- ~~设备插拔检测~~ - 集成scrcpy -- 视觉反馈 +- ~~视觉反馈~~ + - ~~页面切换加载进度条~~ - ~~页面切换动画效果~~ - ~~安装应用进度条~~