PyQt5.12版本No module named ‘PyQt5.QtWebEngineWidgets’

  • A+

在python的gui编程中pyqt5是比较成熟的框架,于是老早就安装了当时的最新版pyqt5 5.11版并编写了一些程序。在使用到QWebEngineView时感觉非常喜欢,想到以后可以直接通过加载网页并运行js脚本即可做出一个gui桌面程序。然而,然而,也正是因为这个QWebEngineView,我掉进了一个深坑,一整天费劲心思的一点点排查,硬是没出来。后来安装了最新版的pyqt5.12同时安装了QtWebEngineWidgets5.12版本就没事了,真是太坑了。具体记录如下:

pyqt5程序编写

首先使用QWebEngineView及QMainWindow来创建一个界面,并加载百度网盘url

  1. from PyQt5.QtCore import QUrl
  2. from PyQt5.QtWidgets import QMainWindow, QApplication, QAction, QMenu, QLabel
  3. from PyQt5.QtWebEngineWidgets import QWebEngineView
  4. from PyQt5.QtGui import QIcon
  5. class MainPanel(QMainWindow):
  6.     def __init__(self, parent=None, *args, **kwargs):
  7.         super(MainPanel, self).__init__(parent, *args, **kwargs)
  8.         self.cookies = dict()
  9.         self.checked_file_list = list()
  10.         self.login_statue = False
  11.         self.register_statue = (FalseFalse)
  12.         self.browser = QWebEngineView()
  13.         self.menu_bar = self.menuBar()
  14.         self.status_bar = self.statusBar()
  15.         self.init_menu()
  16.         self.change_action_enable_statue(self.login_statue)
  17.         self.init_ui()
  18.     def init_ui(self):
  19.         self.setWindowTitle('百度网盘批量处理大师')
  20.         self.setMinimumSize(512, 330)
  21.         self.setWindowIcon(QIcon("D:\\github\\bdmaster\\app\\resource\\images\\bitbug_favicon.ico"))
  22.         self.setCentralWidget(self.browser)
  23.         self.browser.load(QUrl('https://pan.baidu.com'))
  24.         # self.browser.setContextMenuPolicy(Qt.CustomContextMenu)
  25.         # self.browser.customContextMenuRequested.connect(self.browser_custom_menu)
  26.         self.status_bar.addPermanentWidget(QLabel('http://blog.az009.com'), stretch=0)
  27.     def browser_custom_menu(self, pos):
  28.         menu = QMenu()
  29.         menu.addAction('添加')
  30.         menu.addAction('删除')
  31.         menu.addAction('新建')
  32.         glob_pos = self.mapToGlobal(pos)
  33.         select_action = menu.exec_(glob_pos)
  34.         if select_action:
  35.             if select_action.text() == '添加':
  36.                 print('处理添加部分的逻辑代码')
  37.             elif select_action.text() == '删除':
  38.                 print('处理删除部分的逻辑代码')
  39.             else:
  40.                 print('处理新建部分的逻辑代码')
  41.     def init_menu(self):
  42.         self.file_menu = self.menu_bar.addMenu('文件(&Z)')
  43.         self.rename_menu = self.menu_bar.addMenu('批量重命名(&R)')
  44.         self.share_menu = self.menu_bar.addMenu('批量分享(&S)')
  45.         self.resave_menu = self.menu_bar.addMenu('批量转存(&Z)')
  46.         self.unline_menu = self.menu_bar.addMenu('批量离线(&L)')
  47.         self.sync_menu = self.menu_bar.addMenu('批量同步(&T)')
  48.         self.other_menu = self.menu_bar.addMenu('其他批量(&L)')
  49.         self.help_menu = self.menu_bar.addMenu('软件帮助(&H)')
  50.         self.exit_action = QAction('&退出', self)
  51.         self.exit_action.setShortcut('Ctrl+Q')
  52.         self.exit_action.setStatusTip('退出应用软件')
  53.         self.file_menu.addAction(self.exit_action)
  54.         self.kename_action = QAction('&关键词替换', self)
  55.         self.kename_action.setShortcut('Ctrl+K')
  56.         self.kename_action.setStatusTip('批量将文件或文件夹修改为指定的名称')
  57.         self.rename_menu.addAction(self.kename_action)
  58.         self.exname_action = QAction('&修改拓展名', self)
  59.         self.exname_action.setIcon(QIcon(''))
  60.         self.exname_action.setShortcut('Ctrl+E')
  61.         self.exname_action.setStatusTip('将文件拓展名称改为指定的类型')
  62.         self.rename_menu.addAction(self.exname_action)
  63.         self.orname_action = QAction('&添加序号', self)
  64.         self.orname_action.setShortcut('Ctrl+O')
  65.         self.orname_action.setStatusTip('将文件夹中的文件按照指定的字段排序后添加序号')
  66.         self.rename_menu.addAction(self.orname_action)
  67.         self.rename_action = QAction('&正则替换', self)
  68.         self.rename_action.setShortcut('Ctrl+R')
  69.         self.rename_action.setStatusTip('通过输入正则表达式来进行替换')
  70.         self.rename_menu.addAction(self.rename_action)
  71.         self.finame_action = QAction('&全盘搜索替换', self)
  72.         self.finame_action.setShortcut('Ctrl+F')
  73.         self.finame_action.setStatusTip('根据关键词对全盘进行搜索并将关键词替换成需要的,替换成的输入框可留空')
  74.         self.rename_menu.addSeparator()
  75.         self.rename_menu.addAction(self.finame_action)
  76.         self.share_action = QAction('&分享文件', self)
  77.         self.share_action.setShortcut('Ctrl+S')
  78.         self.share_action.setStatusTip('批量分享选中的文件或文件夹')
  79.         self.share_menu.addAction(self.share_action)
  80.         self.save_share_action = QAction('&导出分享', self)
  81.         self.save_share_action.setShortcut('Ctrl+D')
  82.         self.save_share_action.setStatusTip('导出已经分享的文件或文件夹信息')
  83.         self.share_menu.addAction(self.save_share_action)
  84.         self.haspwd_action = QAction('&有密链接', self)
  85.         self.haspwd_action.setShortcut('Ctrl+H')
  86.         self.haspwd_action.setStatusTip('批量转存带密码的链接资源到自己的网盘')
  87.         self.resave_menu.addAction(self.haspwd_action)
  88.         self.nopwd_action = QAction('&无密链接', self)
  89.         self.nopwd_action.setShortcut('Ctrl+J')
  90.         self.nopwd_action.setStatusTip('批量转存无密码的链接资源到自己的网盘')
  91.         self.resave_menu.addAction(self.nopwd_action)
  92.         self.use_action = QAction('&使用教程', self)
  93.         self.use_action.setShortcut('Ctrl+U')
  94.         self.use_action.setStatusTip('关于软件的操作使用教程')
  95.         self.help_menu.addAction(self.use_action)
  96.         self.contact_action = QAction('&联系反馈', self)
  97.         self.contact_action.setShortcut('Ctrl+L')
  98.         self.contact_action.setStatusTip('联系作者&反馈问题')
  99.         self.help_menu.addAction(self.contact_action)
  100.         self.register_action = QAction('&软件注册', self)
  101.         self.register_action.setShortcut('Ctrl+G')
  102.         self.register_action.setStatusTip('获取软件注册序列号')
  103.         self.help_menu.addAction(self.register_action)
  104.         self.about_action = QAction('&关于软件', self)
  105.         self.about_action.setShortcut('Ctrl+A')
  106.         self.about_action.setStatusTip('关于软件的一些说明')
  107.         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文件,这样才能显示图标,具体方式在后面开篇讲解。

weinxin
我的微信公众号
爱真理,得永生!          爱在灵灵久博客,网罗天下,福利大家!

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: