跟着鬼哥学PyQtPart.4

来源:互联网 发布:quartus mac系统 编辑:程序博客网 时间:2024/06/02 12:59

中秋假期转眼已经过去两天了,我们的学习也在不断向前,经过前面三篇文章的学习,我们已经可以做出来一个简单的反编译apk的工具了。

为了更方便的使用我们自己编写的工具,所以我们对于第三篇文章中的search_file button来进行处理,我们使用拖拽文件到QLineEdit控件上面来显示文件路径,而不用打开window来选择了,这样对我们的操作来说更加方便一点。

 

0x1:拖拽事件的处理

拖拽事件,经过一晚上的查询以及翻看Java已经写好的工具,终于找到dragEnterEventdropEvent两个事件。关于这两个事件的详细介绍,自行google搜索一下即可。

要想使用这个事件,我们需要重写一下QLineEdit控件,并且在其init方法里面设置setAcceptDropsTrue来接收拖拽事件。

所以现在的问题就是我们如何来获取得到拖入文件的路径呢?

经过查询mimeData有一些方法可以参考,经过测试,urls()属性还是比较贴近我们所需的,但是还需要对其进行处理得到文件路径。

详细代码如下:


def dropEvent(self, event):        ###获取拖放过来的文件的路径        st=str(event.mimeData().urls())        print(st)        ###这里没发现好的api,所以用mimeData()的urls属性了,text()不好用,所以下面就是字符串截取,来还原路径        a='///'        b=')]'                num2=st.index(b)-1        num=st.index(a)+3        st=st[num:num2]        ##这里定义全局变量,拖入文件或者文件夹的路径        global APK_STR        APK_STR=st                    self.setText(st)



0x2:重新做一下布局文件

详细代码如下,有详细注释,这里不再多说:


 QWidget.__init__(self, parent)        self.setWindowTitle('Android_APK')        ###第一行        self.apk_decode=QPushButton("Apk_Decode")        self.apk_path_edit = MyEditText(self)                ###第二行,三个按钮,这里第三个按钮的点击事件还没写        self.apk_build=QPushButton("Apk_Build")        self.apk_build_edit = MyEditText()        ###第三行        self.sign = QPushButton("Apk_Sign")        self.apk_sign_edit = MyEditText()        ##第四行        self.shootcut=QPushButton("Shoot_Cut")        self.shootcut_text=QLabel("please keep moile with usb")                ###布局文件的编写,四行两列        grid = QGridLayout()        grid.setSpacing(10)        grid.addWidget(self.apk_decode, 1, 0)        grid.addWidget(self.apk_path_edit, 1, 1)                grid.addWidget(self.apk_build, 2, 0)        grid.addWidget(self.apk_build_edit, 2, 1)        grid.addWidget(self.sign,3,0)        grid.addWidget(self.apk_sign_edit, 3,1)        grid.addWidget(self.shootcut,4,0)        grid.addWidget(self.shootcut_text, 4,1)                ###设置窗口的高宽,将gridview放入大布局中        self.setLayout(grid)        self.resize(450, 300)


效果图如下:





0x3:整合相关按钮的点击事件

 

前面一篇文章已经将反编译的按钮事件做好,所以这里我们照着写一下回编译和签名以及最后的截屏事件即可。



def apkD(self):        ###上面openFIle方法中定义的全局变量,打印一下路径,看看是否正确#####        print(APK_STR)        ###apktool的命令使用#####        apkToD='java -jar apktool.jar d '+APK_STR        ###调用os的system命令来执行cmd的相关命令###        os.system(apkToD)    def apkB(self):        ###上面openFIle方法中定义的全局变量,打印一下路径,看看是否正确#####        print(APK_STR)        ###apktool的命令使用#####        apkToD='java -jar apktool.jar b '+APK_STR        ###调用os的system命令来执行cmd的相关命令###        os.system(apkToD)    def apkS(self):        apkSign='java -jar signapk.jar testkey.x509.pem testkey.pk8 '+APK_STR+' Signed_apk.apk'        print apkSign        ###调用os的system命令来执行cmd的相关命令###        os.system(apkSign)    def shootCut(self):        pre_com='adb wait-for-device'        os.system(pre_com)        ###将截图保存到local下        fir_com='adb shell screencap -p /data/local/tmp/tmp.png'        print (fir_com)        os.system(fir_com)                ###当前时间,精确到秒,来保存图片命名        timestamp = time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime(time.time()))        path=os.getcwd()        ###将其导出来        sec_com='adb pull /data/local/tmp/tmp.png '+path+'\\'+timestamp+'.png'        print(sec_com)        os.system(sec_com)        thi_com='adb shell rm /data/local/tmp/tmp.png'        os.system(thi_com)



0x4:完整的代码

下面附上完整的代码,有兴趣的朋友,直接测试即可。记得先配置好pyqt相关开发环境。


# -*- coding: utf-8 -*-from PyQt4.QtGui import *from PyQt4.QtCore import *import sysimport osimport timeclass MainLayout(QWidget):        def __init__(self, parent=None):                QWidget.__init__(self, parent)        self.setWindowTitle('Android_APK')        ###第一行        self.apk_decode=QPushButton("Apk_Decode")        self.apk_path_edit = MyEditText(self)                ###第二行,三个按钮,这里第三个按钮的点击事件还没写        self.apk_build=QPushButton("Apk_Build")        self.apk_build_edit = MyEditText()        ###第三行        self.sign = QPushButton("Apk_Sign")        self.apk_sign_edit = MyEditText()        ##第四行        self.shootcut=QPushButton("Shoot_Cut")        self.shootcut_text=QLabel("please keep moile with usb")        ###反编译按钮的点击事件        self.connect(self.apk_decode,SIGNAL('clicked()'),self.apkD)        ###回编译按钮的点击事件        self.connect(self.apk_build,SIGNAL('clicked()'),self.apkB)        ###签名按钮的点击事件        self.connect(self.sign,SIGNAL('clicked()'),self.apkS)        ###截屏按钮的点击事件        self.connect(self.shootcut,SIGNAL('clicked()'),self.shootCut)                ###布局文件的编写,四行两列        grid = QGridLayout()        grid.setSpacing(10)        grid.addWidget(self.apk_decode, 1, 0)        grid.addWidget(self.apk_path_edit, 1, 1)                grid.addWidget(self.apk_build, 2, 0)        grid.addWidget(self.apk_build_edit, 2, 1)        grid.addWidget(self.sign,3,0)        grid.addWidget(self.apk_sign_edit, 3,1)        grid.addWidget(self.shootcut,4,0)        grid.addWidget(self.shootcut_text, 4,1)                ###设置窗口的高宽,将gridview放入大布局中        self.setLayout(grid)        self.resize(450, 300)             ''''def openFile(self):        ##调用QfileDialog的相关方法来打开文件选择框        s=QFileDialog.getOpenFileName(self,"Open file dialog","/","Apk files(*.apk)")        ##定义全局变量,用于接收需要反编译的apk的路径        global APK_STR        APK_STR=str(s)        self.apk_path_edit.setText(APK_STR)'''    def apkD(self):        ###上面openFIle方法中定义的全局变量,打印一下路径,看看是否正确#####        print(APK_STR)        ###apktool的命令使用#####        apkToD='java -jar apktool.jar d '+APK_STR        ###调用os的system命令来执行cmd的相关命令###        os.system(apkToD)    def apkB(self):        ###上面openFIle方法中定义的全局变量,打印一下路径,看看是否正确#####        print(APK_STR)        ###apktool的命令使用#####        apkToD='java -jar apktool.jar b '+APK_STR        ###调用os的system命令来执行cmd的相关命令###        os.system(apkToD)    def apkS(self):        apkSign='java -jar signapk.jar testkey.x509.pem testkey.pk8 '+APK_STR+' Signed_apk.apk'        print apkSign        ###调用os的system命令来执行cmd的相关命令###        os.system(apkSign)    def shootCut(self):        pre_com='adb wait-for-device'        os.system(pre_com)        ###将截图保存到local下        fir_com='adb shell screencap -p /data/local/tmp/tmp.png'        print (fir_com)        os.system(fir_com)                ###当前时间,精确到秒,来保存图片命名        timestamp = time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime(time.time()))        path=os.getcwd()        ###将其导出来        sec_com='adb pull /data/local/tmp/tmp.png '+path+'\\'+timestamp+'.png'        print(sec_com)        os.system(sec_com)        thi_com='adb shell rm /data/local/tmp/tmp.png'        os.system(thi_com)        class MyEditText(QLineEdit):        def __init__(self,parent=None):                super(MyEditText,self).__init__(parent)        #这里在init初始化,接受拖入事件        self.setAcceptDrops(True)            ###重写两个拖入文件的操作方法    def dragEnterEvent(self,event):        event.accept()    def dropEvent(self, event):        ###获取拖放过来的文件的路径        st=str(event.mimeData().urls())        print(st)        ###这里没发现好的api,所以用mimeData()的urls属性了,text()不好用,所以下面就是字符串截取,来还原路径        a='///'        b=')]'                num2=st.index(b)-1        num=st.index(a)+3        st=st[num:num2]        ##这里定义全局变量,拖入文件或者文件夹的路径        global APK_STR        APK_STR=st                    self.setText(st)###程序的主入口if __name__ == "__main__":           app = QApplication(sys.argv)    qb = MainLayout()    qb.show()    sys.exit(app.exec_())




效果图,前面几篇基本都有了,这里不再贴出了。

注意:

1.反编译采用的是apktool.jar的命令,所以得将其放到.py文件对应目录

2.签名采用google的公钥来过的,所以其文件也必须在同目录下

3.截屏动作,得保证手机正常连接usbadb进程不被占用,所以如果读者有自己编译的adb是最好的,若此功能不好用,直接做个cmd脚本将上述方法中的命令放入即可

4.这四篇文章,仅记录一下PyQt的相关学习过程,读者可以随意对其进行扩展开发,做一个IDE工具集合搜索,修改,保存以及一些自动化工具

结束语:

虽然中秋几天假期没有出去玩,不过从头开始学习PyQt还是有一些进步的。代码方面编写肯定是有很多疏漏,其对应功能方面也可以做更多优化,有兴趣的朋友,请继续加油。

仅以一句话勉励自己:

勤能补拙是良训,一分辛苦一分才。

 

相关附件之类的,我就上传到百度网盘了:


 http://pan.baidu.com/s/1o6sONoQ


1 0
原创粉丝点击