记录使用pyQt第一次做图形化界面的经历

目录

1.搭建环境
2.明确需求
3.功能分解
 3.1获取下载目录
 3.2
4.功能实现
5.参考文献

1.搭建环境

  继上次做的那个爬虫之后(详见上期博文:(https://blog.csdn.net/sersan/article/details/90142760))就想在此基础上做一个图形化界面。在网上搜了相关教程,决定选用Eric+pyQt来做。
  首先是Eric的安装,直接在官网下载(http://eric-ide.python-projects.org/eric-download.html),解压后如图1-1所示,然后执行install.py程序(参考5.1),他就会自动扫描要安装的包并使用pip下载缺失的包,不过这个下载速度实在太慢了,好在可以复制下载链接用idm下载后手动安装。在经过几次手动下载安装后,再执行install.py就成功了,安装过程如图1-2所示。
记录使用pyQt第一次做图形化界面的经历_第1张图片记录使用pyQt第一次做图形化界面的经历_第2张图片

         图1-1Eric安装包                      图1-2 安装过程
  然后下载Qt designer,开始设计吧。期间还遇到个小问题,在Eric中不能自动打开Qt designer,解决方法见参考5.2。

2.明确需求

  我希望实现的功能有:
  >选择下载目录
  >是否保存图书信息选项
  >信息显示窗口
  >开始和停止下载按钮
  >关于软件菜单
  使用Qt designer设计出的ui如图2-1所示。
           记录使用pyQt第一次做图形化界面的经历_第3张图片
                            图2-1 ui界面

3.功能分解

  利用Eric直接生成槽函数

3.1 选择下载目录

  按下按钮1,打开一个选择窗口(参考5.3),选择目录并显示在lineEdit上。lineEdit的默认提示参考了5.4,可以在UI设计时选择,很方便。

    def on_toolButton_clicked(self):
        """
        下载目录的输入,打开一个目录选择窗口
        """
        my_file_name = QFileDialog.getExistingDirectory(self,  "选择下载保存目录:",   "C:\")
        put_info = '您下载的文件将保存在 ' + my_file_name
        self.textBrowser.append(put_info)
        self.save_path = my_file_name
        self.lineEdit.setText(my_file_name)
        return my_file_name
3.2 开始下载和停止下载

  想着要利用上次写的代码,就直接使用from ITbook_spider import All_itebooks_Spider将上次写的那个类引了进来,在按下按钮2后运行All_itebooks_Spider.start(),再经过简单修改传递了保存目录和判断是否保存图书信息的参数之后,运行程序,结果可想而知,卡死了(而且这样要怎么退出呢。。。因为是小白,很多可能很简单就能解决的问题就是不知道。。。)。这是因为整个程序只开了一个线程,启动爬虫后一直再循环,处理大量信息,主窗口的功能就完全无法进行了,在网上看了些pyQt多线程的教程也没弄懂怎么实现的(关于多线程,可以看下参考5.5);之后突然想到了另一条路,就是先把爬虫程序打包成exe,在用pyQt程序去调用他,由此,展开了另一场旅程。。。。

3.2.1 pyinstaller打包

  打包的过程自然也不轻松,一开始就遇到了AttributeError: ‘str’ object has no attribute ‘items’'错误,参考了5.6发现我们居然是一个错误,将setuptools升了个级,继续打包,又报了UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xce in position错误,参考5.7将CMD环境通过切换为UTF-8代码页,尝试了几次后终于成功了。最后生成的文件大小500多MB,Σ(⊙▽⊙"a!!!,有点恐怖,参考5.8中提到了原因,我用的这个虚拟环境环境中装了太多杂七杂八的包了。。。但是不想改了,就这样吧。

3.2.2 python调研外部程序并传参

  先在已经有了exe,运行起来似乎也没问题(。。。||),要怎么调用呢,在参考了5.9之后,我想用subprocess.Popen(r’cmd’)实现,博主说这是异步的,正是我想要的。然后用空格传递参数(传参方式也挺别致的:'xxx.exe '+" “+save_path+” "+my_decision(参考了5.10),结果并没成功ε=(´ο`*)))。在看了参考5.11的文章后总算弄懂了,原来是我的爬虫程序根本没有外部传参入口流( -_-|| ),使用sys.argv进行外部传参,在重新打包,试了下果然能够通过subprocess.Popen()就调动成功了(更多subprocess.Popen()详情,可以参考5.12)。后来看到了参考5.13发现换成os.system()就可以,只是不能用start /wait模式,否则又会卡死,因为他会等待调用的程序执行完才会继续主程序,显然等不到的。最后参考了5.14使用start /b启动就能达到和subprocess.Popen()同样的效果了。具体代码如下:

    @pyqtSlot()
    def on_pushButton_5_clicked(self):
        """
        开始下载按钮
        """
        self.textBrowser.append("即将开始下载,请稍后...")
        # 还可以通过os.system()返回的info_1判断是否打开成功,成功会返回0(int类型)
        info_1 = os.system('start /b cmd.exe @cmd /k ITbook_spider\ITbook_spider.exe ' + " "+self.save_path+" "+str(self.my_decision))
        if info_1 == 0:
            self.textBrowser.append("下载任务建立成功,正在下载...")
        else:
            self.textBrowser.append("任务失败,请重新启动")

  至此,开始下载功能总算实现了,接下来的停止下载也很简单,参考了5.9和参考5.13都介绍了一种方法关闭进程,具体代码如下:

    @pyqtSlot()
    def on_pushButton_6_clicked(self):
        """
        停止下载按钮
        """
        self.textBrowser.append("正在关闭下载任务...")
        info_2 = os.system(r'taskkill /F /IM ITbook_spider.exe')
        if info_2 == 0:
            self.textBrowser.append("关闭成功")
        else:
            self.textBrowser.append("出bug了,关闭失败")
3.3 是否保存图书信息选项

  这两项就简单了,只用给调用的传个参数就行了,但是使用sys.argv传的参数是str类型的,我想转成bool试了几个方法都不方便,就直接将传入的参数转成str了(即def on_pushButton_5_clicked()中的str(self.my_decision)参数)。

@pyqtSlot()
    def on_radioButton_clicked(self):
        """
        是否保存图书信息的是选项
        """
        self.my_decision = self.radioButton.isChecked()
        put_info_2 = "图书信息将保存在"+self.save_path
        self.textBrowser.append(put_info_2)

    
    @pyqtSlot()
    def on_radioButton_2_clicked(self):
        """
        是否保存图书信息的否选项
        """
        self.my_decision = self.radioButton.isChecked()
        put_info_3 = "图书信息将不会被保存"
        self.textBrowser.append(put_info_3)

3.4 关于菜单

  为了使关于菜单更加美观,我新设计了一个ui窗口,增加了Dialog类。并通过my_info = Dialog()调用,my_info.exec_()显示。

    @pyqtSlot()
    def on_action1_triggered(self):
        """
        关于菜单
        """
        my_info = Dialog()
        my_info.exec_()
    
    @pyqtSlot()
    def on_action2_triggered(self):
        """
        关于pyQt菜单
        """
        QMessageBox.aboutQt(self,  'ABOUT QT')
3.5 信息显示

  这个功能没有实现。。。没找到被调用程序外部传参的方法o( ̄︶ ̄)o(其实重新编写爬虫代码,比起把他们这样组合要更简单吧-_-||),而且要是在textBrowser上显示下载详情,估计又得用到多线程┓( ´∀` )┏。所以textBrowser上只能显示诸如“下载目录”、“开始下载”、“停止下载”等触发信息了,点了开始下载按钮后就两眼一抹黑,其实想想这样也挺好。。。


  就这样了!到此结束。最后还要感谢下面那些文章给与我的帮助,参考5.15 、参考5.16和参考5.17给我写博文的指导。

5.参考文献

5.1 win下搭建python3+PyQt5+eric6环境(https://www.cnblogs.com/ljd4you/p/7978407.html)
5.2 使用Eric6打不开Qt designer的原因小记(https://blog.csdn.net/weixin_41965380/article/details/84864418)
5.3 python qt(pyqt)的文件打开、文件保存、文件夹选择对话框(https://blog.csdn.net/jirryzhang/article/details/59088964)
5.4 QLineEdit默认提示 setPlaceholderText(https://blog.csdn.net/zhangxuechao_/article/details/82257914)
5.5 PyQt5进阶(二)——多线程:QThread & 事件处理(https://blog.csdn.net/qq_34710142/article/details/80936986)
5.6 Pyinstaller打包过程中报错“AttributeError: ‘str’ object has no attribute ‘items’’”问题解决
  (https://blog.csdn.net/Together_CZ/article/details/88538787)
5.7 Pyinstaller打包出现UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xce in position 解决方案
  (https://blog.csdn.net/qq_35203425/article/details/80992870)
5.8 python打包成exe,太大了该怎么解决?(https://blog.csdn.net/qq_24624539/article/details/88074501)
5.9 python3 打开外部程序及关闭 (https://blog.csdn.net/weixin_41972401/article/details/80339992)
5.10 Python调用外部程序——os.system()和subprocess.call()(https://www.cnblogs.com/songwenlong/p/5940155.html)
5.11 “if name=='main():”(https://blog.csdn.net/u012175219/article/details/51264345)
5.12 python的subprocess.Popen()的简单用法(https://blog.csdn.net/sinat_36219858/article/details/70186649)
5.13 python 使用多进程打开多个cmd窗口,并在子进程结束之后关闭cmd窗口(https://www.cnblogs.com/love-DanDan/p/10789121.html)
5.14 start /wait 命令(https://www.cnblogs.com/top5/archive/2011/06/25/2090189.html)
5.15 如何在写CSDN博客时,调节字体大小、颜色和段落首行缩进(https://blog.csdn.net/weixin_39127080/article/details/87828934)
5.16 CSDN:图片的换行显示与并排显示(https://blog.csdn.net/yiminghd2861/article/details/89789358)
5.17 170715 如何更改CSDN上传图片大小(https://blog.csdn.net/qq_33039859/article/details/75147059)

你可能感兴趣的:(图形化界面,python笔记,pyQt,Eric,图形化界面)