- A+
在python的gui编程中pyqt5是比较成熟的框架,于是老早就安装了当时的最新版pyqt5 5.11版并编写了一些程序。在使用到QWebEngineView时感觉非常喜欢,想到以后可以直接通过加载网页并运行js脚本即可做出一个gui桌面程序。然而,然而,也正是因为这个QWebEngineView,我掉进了一个深坑,一整天费劲心思的一点点排查,硬是没出来。后来安装了最新版的pyqt5.12同时安装了QtWebEngineWidgets5.12版本就没事了,真是太坑了。具体记录如下:
pyqt5程序编写
首先使用QWebEngineView及QMainWindow来创建一个界面,并加载百度网盘url
- from PyQt5.QtCore import QUrl
- from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QMenu, QLabel
- from PyQt5.QtWebEngineWidgets import QWebEngineView
- from PyQt5.QtGui import QIcon
- class MainPanel(QMainWindow):
- def __init__(self, parent=None, *args, **kwargs):
- super(MainPanel, self).__init__(parent, *args, **kwargs)
- self.cookies = dict()
- self.checked_file_list = list()
- self.login_statue = False
- self.register_statue = (False, False)
- self.browser = QWebEngineView()
- self.menu_bar = self.menuBar()
- self.status_bar = self.statusBar()
- self.init_menu()
- self.change_action_enable_statue(self.login_statue)
- self.init_ui()
- def init_ui(self):
- self.setWindowTitle('百度网盘批量处理大师')
- self.setMinimumSize(512, 330)
- self.setWindowIcon(QIcon("D:\\github\\bdmaster\\app\\resource\\images\\bitbug_favicon.ico"))
- self.setCentralWidget(self.browser)
- self.browser.load(QUrl('https://pan.baidu.com'))
- # self.browser.setContextMenuPolicy(Qt.CustomContextMenu)
- # self.browser.customContextMenuRequested.connect(self.browser_custom_menu)
- self.status_bar.addPermanentWidget(QLabel('http://blog.az009.com'), stretch=0)
- def browser_custom_menu(self, pos):
- menu = QMenu()
- menu.addAction('添加')
- menu.addAction('删除')
- menu.addAction('新建')
- glob_pos = self.mapToGlobal(pos)
- select_action = menu.exec_(glob_pos)
- if select_action:
- if select_action.text() == '添加':
- print('处理添加部分的逻辑代码')
- elif select_action.text() == '删除':
- print('处理删除部分的逻辑代码')
- else:
- print('处理新建部分的逻辑代码')
- def init_menu(self):
- self.file_menu = self.menu_bar.addMenu('文件(&Z)')
- self.rename_menu = self.menu_bar.addMenu('批量重命名(&R)')
- self.share_menu = self.menu_bar.addMenu('批量分享(&S)')
- self.resave_menu = self.menu_bar.addMenu('批量转存(&Z)')
- self.unline_menu = self.menu_bar.addMenu('批量离线(&L)')
- self.sync_menu = self.menu_bar.addMenu('批量同步(&T)')
- self.other_menu = self.menu_bar.addMenu('其他批量(&L)')
- self.help_menu = self.menu_bar.addMenu('软件帮助(&H)')
- self.exit_action = QAction('&退出', self)
- self.exit_action.setShortcut('Ctrl+Q')
- self.exit_action.setStatusTip('退出应用软件')
- self.file_menu.addAction(self.exit_action)
- self.kename_action = QAction('&关键词替换', self)
- self.kename_action.setShortcut('Ctrl+K')
- self.kename_action.setStatusTip('批量将文件或文件夹修改为指定的名称')
- self.rename_menu.addAction(self.kename_action)
- self.exname_action = QAction('&修改拓展名', self)
- self.exname_action.setIcon(QIcon(''))
- self.exname_action.setShortcut('Ctrl+E')
- self.exname_action.setStatusTip('将文件拓展名称改为指定的类型')
- self.rename_menu.addAction(self.exname_action)
- self.orname_action = QAction('&添加序号', self)
- self.orname_action.setShortcut('Ctrl+O')
- self.orname_action.setStatusTip('将文件夹中的文件按照指定的字段排序后添加序号')
- self.rename_menu.addAction(self.orname_action)
- self.rename_action = QAction('&正则替换', self)
- self.rename_action.setShortcut('Ctrl+R')
- self.rename_action.setStatusTip('通过输入正则表达式来进行替换')
- self.rename_menu.addAction(self.rename_action)
- self.finame_action = QAction('&全盘搜索替换', self)
- self.finame_action.setShortcut('Ctrl+F')
- self.finame_action.setStatusTip('根据关键词对全盘进行搜索并将关键词替换成需要的,替换成的输入框可留空')
- self.rename_menu.addSeparator()
- self.rename_menu.addAction(self.finame_action)
- self.share_action = QAction('&分享文件', self)
- self.share_action.setShortcut('Ctrl+S')
- self.share_action.setStatusTip('批量分享选中的文件或文件夹')
- self.share_menu.addAction(self.share_action)
- self.save_share_action = QAction('&导出分享', self)
- self.save_share_action.setShortcut('Ctrl+D')
- self.save_share_action.setStatusTip('导出已经分享的文件或文件夹信息')
- self.share_menu.addAction(self.save_share_action)
- self.haspwd_action = QAction('&有密链接', self)
- self.haspwd_action.setShortcut('Ctrl+H')
- self.haspwd_action.setStatusTip('批量转存带密码的链接资源到自己的网盘')
- self.resave_menu.addAction(self.haspwd_action)
- self.nopwd_action = QAction('&无密链接', self)
- self.nopwd_action.setShortcut('Ctrl+J')
- self.nopwd_action.setStatusTip('批量转存无密码的链接资源到自己的网盘')
- self.resave_menu.addAction(self.nopwd_action)
- self.use_action = QAction('&使用教程', self)
- self.use_action.setShortcut('Ctrl+U')
- self.use_action.setStatusTip('关于软件的操作使用教程')
- self.help_menu.addAction(self.use_action)
- self.contact_action = QAction('&联系反馈', self)
- self.contact_action.setShortcut('Ctrl+L')
- self.contact_action.setStatusTip('联系作者&反馈问题')
- self.help_menu.addAction(self.contact_action)
- self.register_action = QAction('&软件注册', self)
- self.register_action.setShortcut('Ctrl+G')
- self.register_action.setStatusTip('获取软件注册序列号')
- self.help_menu.addAction(self.register_action)
- self.about_action = QAction('&关于软件', self)
- self.about_action.setShortcut('Ctrl+A')
- self.about_action.setStatusTip('关于软件的一些说明')
- self.help_menu.addAction(self.about_action)
使用pyinstaller对pyqt5程序打包
将上述代码及相应的数据接口合并,并在pycharm中也能够正常的运行,同时使用pyinstaller对其进行打包成exe文件的过程中,一切JavaScript脚本都添加ok,然而在打包好的exe运行时控制台中却不停的弹出mamager server.cc什么的文件,程序一直无法打开百度网盘的网页。
于是一点点排查,刚开始还以为数据接口因为运行了qthread多线程出现问题,就将ui界面与数据接口分离,果然有效了,打包ui界面不再出现无法打开百度网盘网址的问题。这也导致了一天错误爬坑的开始,对数据接口逐一的排查,逐一的排查,逐一的排查,后来在排查过程中出现了一个矛盾的现象,就开始怀疑是不是pyqt5是不是出现了问题,看了一眼pycharm设置中的包更新提示,果然在更新了pyqt5并更新了QWebEngineView到5.12版本后上面的深坑自然填平了。想想真是杯具,爬了一天的坑,汗把水流。
pyqt5 5.12版QWebEngineView5.12版安装
在安装好pyqt5 5.12版本后运行项目出现了
No module named PyQt5.QtWebEngineWidgets QWebEngineView 这是因为在5.12版本中QWebEngineView需要单独进行安装,安装方式也很简单,pip install PyQtWebEngine 然后项目中一切不用改,照常运行即可。
所以在这里提醒大家一定要安装最新版本的pyqt5 以及QWebEngineView
拓展知识
在使用pyinstaller对项目进行打包时最好是用virtualenv建立虚拟环境,并安装项目需要的库,其他多余的包不用安装。pyinstaller打包时会将各种多余的包如numpy、matplotlib等等都导入进去,无用增加软件的大小。第一次打包项目时不要带参数,并将打包后的exe文件拖到cmd命令行中运行看看有没有提示什么错误,并根据错误进行安装相应的包。运行成功后在加相应的参数 如-F -i 'master.ico'等 图标文件要是ico格式,并且在不同平台运行时需要将不同大小的ico文件合并为一个ico文件,这样才能显示图标,具体方式在后面开篇讲解。