极速简约防盗linux全屏浏览器。
背景技术:
::1994年,网景公司推出世界上第一款浏览器,距今26年。目前专业浏览器有:谷歌、360、火狐、ie、edge和qq等,它们的功能齐全,消耗大量内存和cpu资源,拥有多达近百种功能,涵盖:网页基本操作、系统设置、插件和安全设置,其中:插件和安全设置极少使用,而系统设置偶尔使用,常用的功能是:鼠标滚轮上下移动浏览网页、点击超链接打开新网页、前进、后退、刷新、保存图片等网页基本操作。专业浏览器除了功能繁琐外还有两大弊端:1、非默认全屏显示,需按不常用的f11功能键切换全屏显示,既不方便,也不普及;2、企业员工上网容易外传客户和技术资料造成泄密。因此,针对企业防盗上网需求、普通大众简单上网需求和全屏视觉享受,迫切需要推出一种功能简洁、浏览快速且防盗的全屏浏览器。开发浏览器的语言从最初的c/c 逐步转向python,因为python有最庞大的第三方生态圈。pyqt开发商是英国的riverbankcomputing公司,该公司使用了芬兰digia公司的qt图形界面开发模块。pyqt是qt和python结合的产物,是为了将qt的功能用于python开发的包装器。pyqt5是5.x版本,pyqt5由三大软件模块组成:pyqt5-sip、pyqt5和pyqt5-tools,pyqt5-sip是python生成c 接口代码的工具,能实现标准python和c/c 数据类型之间自动转换;pyqt5提供支持qt5各个类的python模块,放在python目录下的lib\site-packages\pyqt5目录;pyqt5-tools提供qtdesigner供设计ui界面。qt是一个跨平台的c 图形界面程序框架;qt5是qt的第5版本。qt被分成八个模块:1.qtcore模块包含核心的非gui功能;2.qtgui模块包含图形组件和相关的类;3.qtnetwork模块包含了网络编程的类;4.qtxml包含使用xml文件的类;5.qtsvg模块提供可缩放矢量图形;6.qtopengl模块使用opengl库渲染3d和2d图形;7.qtsql模块提供数据库接口的类;8.qtwebengine模块提供了一个简易web浏览器内核,它可较容易地把web内容嵌入到qt应用程序中。qtwebengine架构见图1.qtwebengine的功能分成下列模块:qtwebenginewidgets模块(见图2):用于创建基于widget的web应用.qtwebengine模块:用于创建基于qtquick的web应用.qtwebenginecore模块:与chromium内核交互.备注:qtwebenginecore基于chromium,但没有包含或使用任何chrome浏览器的其它服务和插件,可在chromium项目源代码库查看chromium和chrome的区别。qtwebengineprocess是一个单独的可执行程序,用于呈现网页和执行javascript,这样可缓解安全问题并隔离由特定内容引起的崩溃。一个qwebengineview实例有一个qwebenginepage,每一个qwebenginepage都属于一个qwebengineprofile,qwebengineprofile有一个页面设置的qwebenginesettings。应用程序可使用url和html字符串加载页面到webengineview。qtwebengine将chromium的web功能集成到qt中,其最新版本基于chromium73。技术实现要素:本发明人在与99%超级计算机一致的linux操作系统上(基于centos7.7版),采用最流行的python3.7版语言、pyqt5和pyqtwebengine开发包,发明了极速简约防盗linux全屏浏览器(简称:防盗全屏浏览器)。它的特点是:程序精炼、速度快、界面简洁、防盗和默认全屏显示所有网页,常用网站相同文字和图片二次打开时间不超过1秒,大约0.1秒,有更新的大图片加载略滞后1~2秒。功能有:以著名导航页hao123.com作为默认首页,默认全屏显示所有网页(见图3和图4),按esc键或空格键或alt键可随时切换全屏显示或多页签浏览窗口;按小键盘-减号或鼠标右击菜单的“关闭”功能即可关闭页面;正常输入框输入内容自动退出全屏模式,打开超链接或右击鼠标或关闭当前页就自动进入全屏模式,具备自动全屏模式的特点;可播放音视频和支持文件下载,但不支持需要证书的不常用功能,如:网银转账(正在被手机扫码支付替代),目的是优先提高运行速度。主窗口总是以最大化显示,关闭主窗口或最后一个页面就直接关机,不让使用者接触操作系统桌面和敏感目录,达到保证资料防盗的目的,面向企业防盗上网需求和大众化用户群体。防盗全屏浏览器保留的多页签窗口界面省略了主菜单和功能按钮(见图5),并以最大化窗口展示,只能关闭主窗口,不能缩放;只提供网页鼠标右击菜单功能(见图6、图7和图8)。多页签窗口界面自上而下仅有五部分组成:主窗口标题(浏览器名称)、呈梯形状的多个页签头部、地址栏、网页显示窗口和状态栏。网页文字默认以四号字显示,可以缩放字号。地址栏提示的内容是:双击鼠标清除地址栏,滚轮上滑可还原,实现了与地址栏提示一致的功能。鼠标右击菜单全部是自定义的常用中文菜单,不常用的功能都被省略,如:前进与后退被浏览足迹代替,停止、撤销和重做被省略。右击网页空白处的主菜单功能是:关闭、我的书签、浏览足迹、收藏书签、刷新、时钟、打开下载文件夹、工具箱子菜单、窗口缩放子菜单、书签管理子菜单和hahayaya极速简约防盗linux全屏浏览器的介绍。工具箱子菜单的功能有:简易文档处理、截图、绘图、打印机设置和网络音量设置(见图6)。窗口缩放子菜单的功能有:拉近、拉远和重置(见图7)。书签管理子菜单的功能有:书签导出和书签导入(见图8)。用户点击“我的书签”或“浏览足迹”主功能后,系统自动弹出书签窗口(见图9)或浏览足迹窗口(见图10),并自动把光标移到书签窗口或浏览足迹窗口的第一行,方便操作,点击书签或浏览过的网址就直接全屏显示;右击任一个书签可选择删除。点击主菜单的“收藏书签”会把新书签置顶,最新浏览过的书签也会置顶;浏览足迹中的网址按时间优先排列,最近的排在最前面。还为文件下载进度条添加鼠标右击子菜单:启动、打开下载文件夹、取消和删除。防盗全屏浏览器无论全屏显示,还是多页签窗口显示,关闭主窗口或最后一个页面就直接关机,满足防盗需要;须重写qmainwindow类,修改closeevent方法,调用linux系统命令poweroff-h关闭主机;并屏蔽操作系统入口(参考本发明人的另一个发明专利申请“一种程序预装且屏蔽操作系统入口的应用软件加密技术”,申请号是:2020111821638)。采用单独的固态硬盘安装linux操作系统和防盗全屏浏览器软件,连接电脑usb口,开机自启动浏览器,与主硬盘的windows操作系统或其他操作系统严格隔离,才能达到允许上网且保证资料防盗的目的。极速简约全屏浏览器能推动网站替代电脑客户端软件和手机app,也能逐步淘汰windows操作系统、macos电脑操作系统和苹果ios手机操作系统,因为网站代码具有跨平台兼容性、免安装、免升级、高容错和高普及性的优点,liunx极速简约全屏浏览器可打开所有网页(少量需插件功能的网页除外,如:网银支付);目前,电脑客户端软件和手机app仅有两个优势:1、界面简洁,2、运行速度略快;全屏浏览器同样具备界面简洁的优点,因省略了主窗口、主菜单和功能按钮,并默认全屏展示所有网页,用户感觉不到浏览器的存在;全屏浏览器源代码仅851行,速度大大提高,二次打开网页文字和图片的耗时不超过1秒(有更新的大图片延时不超过2秒),特别是界面完全相同的网页二次打开耗时大约0.1秒(因为本地有图片缓存),应用软件界面一般都保持不变;随着5g通讯的普及,网页浏览速度将会实现飞跃,新版网页标准如能够允许客户端本地存取数据库将最终彻底淘汰电脑客户端软件和手机app。附图说明图1.qtwebeingine架构图2.qtwebenginewidgets模块图3.全屏浏览界面示意图一图4.全屏浏览界面示意图二图5.多页签浏览窗口示意图图6.右击菜单和二级子菜单“工具箱”图7.右击菜单和二级子菜单“窗口缩放”图8.右击菜单和二级子菜单“书签管理”图9.右击菜单之“我的书签”图10.右击菜单之“浏览足迹”。具体实施方式采用linux系统的python3.7版语言、pyqt5和pyqtwebeingine开发包实现“极速简约防盗linux全屏浏览器”,开发平台是pycharmcommunity2019.3版本。防盗全屏浏览器只需要851行源代码,非常精炼、速度极快、界面简洁、操作简单、防盗和默认全屏显示所有网页。注释行以#开头,/是折行连接符,简单易懂的代码不加注释,以节省篇幅,防盗全屏浏览器有程序框架说明、全套代码、音视频编译和程序编译方法共4个步骤,如下:1.防盗全屏浏览器的程序框架说明import...#导入第三方开发包download_item_ls=[]#储存下载任务数组变量webview_group=[]#储存网页实例数组变量webview_parent_group=[]#储存网页父实例数组变量classmyqmenu(qmenu):#重写qmenu菜单类classwebview(qwebengineview):#重写网页展示qwebengineview类classmyqlineedit(qlineedit):#重写qlineedit类classdownloadwidget(qprogressbar):#自定义下载downloadwidget类,继承qprogressbar类classmyqmainwindow(qmainwindow):#重写qmainwindow类classbookmarkwidget(myqmenu):#自定义书签类,继承myqmenu类classbrowser(myqmainwindow):#自定义browser类,调用网页展示webview类,继承myqmainwindow类classmybrowser(myqmainwindow):#自定义mybrowser类,调用browser类,继承myqmainwindow类if__name__=="__main__":#主程序2.防盗全屏浏览器的全套代码importsys,json,os,datetime,warnings,base64fromsubprocessimportpopenfrompyqt5.qtcoreimportqurl,qt,qcoreapplication,pyqtsignal,qdir,qfileinfo,//qstandardpathsfrompyqt5.qtwidgetsimportqapplication,qmainwindow,qlineedit,qtoolbar,qtabwidget,//qwidget,qhboxlayout,qdialog,qpushbutton,qprogressbar,qmenu,qlabel,//qmessagebox,qaction,qtreeview,qfiledialogfrompyqt5.qtguiimportqicon,qdesktopservices,qcursor,qstandarditemmodel,qstandarditemfrompyqt5.qtwebenginewidgetsimportqwebengineview,qwebenginesettings,//qwebenginedownloaditem,qwebenginepagefrompynput.keyboardimportcontroller,key#导入第三方开发包download_item_ls=[]#储存下载任务数组变量webview_group=[]#储存网页实例数组变量webview_parent_group=[]#储存网页父实例数组变量classmyqmenu(qmenu):#重写qmenu菜单类def__init__(self,parent=none):super(myqmenu,self).__init__(parent)defleaveevent(self,qevent):#鼠标离开菜单,就关闭菜单self.close()classwebview(qwebengineview):#重写网页展示qwebengineview类@staticmethoddefminimum_zoom_factor():#定义窗口缩放的最小参数的方法return0.25@staticmethoddefmaximum_zoom_factor():return5def__init__(self,mainwin):super().__init__(mainwin)self.mainwin=mainwindefcreatewindow(self,qwebenginepage_webwindowtype):#创建网页窗口的方法new_webview=webview(self.mainwin)#递归调用本类self.mainwin.create_tab(new_webview)#创建新页签returnnew_webviewclassmyqlineedit(qlineedit):#重写文本编辑行类qlineeditdef__init__(self,parent=none):super(myqlineedit,self).__init__(parent)self.save_text=''#初始化变量self.save_text为空defwheelevent(self,event):#滚轮处理方法angle=event.angledelta()/8angley=angle.y()#竖直滚过的距离ifangley>=0:#滚轮向上滑动iflen(self.save_text)>0:self.settext(self.save_text)#若原来文本框有内容,则还原文本框内容else:self.save_text=str(self.text())#滚轮向下滑动,则暂储存文本框的内容到变量self.save_textself.settext('')#清空文本框defmousepressevent(self,event):#鼠标点击文本框,延时35毫秒闪一下消息对话框,避免有两个光标message=qmessagebox()message.setwindowtitle('')message.setstandardbuttons(qmessagebox.ok)message.button(qmessagebox.ok).animateclick(35)message.exec_()defmousedoubleclickevent(self,event):#处理鼠标双击的方法self.save_text=str(self.text())#暂储存文本框的内容到变量self.save_textself.settext('')#清空文本框classdownloadwidget(qprogressbar):#自定义文件下载类,自成一体,通俗易懂,不作注释,节省篇幅finished=pyqtsignal()remove_requested=pyqtsignal()def__init__(self,download_item):super(downloadwidget,self).__init__()self._download_item=download_itemdownload_item.finished.connect(self._finished)self.total__bytes=download_item.totalbytes()path=download_item.path()download_item.downloadprogress.connect(self._download_progress)self.setmaximumwidth(250)description=qfileinfo(path).filename()description_length=len(description)ifdescription_length>30:description='{}...{}'.format(description[0:10],//description[description_length-10:])self.setformat('{}%p%'.format(description))self.setorientation(qt.horizontal)self.setminimum(0)self.setvalue(0)self.setmaximum(100)self._update_tool_tip(self.total__bytes)@staticmethoddefopen_file(file):qdesktopservices.openurl(qurl.fromlocalfile(file))@staticmethoddefopen_download_directory():path=qstandardpaths.writablelocation(qstandardpaths.downloadlocation)downloadwidget.open_file(path)defstate(self):returnself._download_item.state()def_update_tool_tip(self,total_bytes):path=self._download_item.path()tool_tip="{}\n{}".format(self._download_item.url().tostring(),//qdir.tonativeseparators(path))total_bytes=self._download_item.totalbytes()iftotal_bytes>0:tool_tip ="\n{}兆".format(round(total_bytes/1024/1024,2))state=self.state()ifstate==qwebenginedownloaditem.downloadrequested:tool_tip ="\n(requested)"elifstate==qwebenginedownloaditem.downloadinprogress:tool_tip =//"\n(downloading...)"elifstate==qwebenginedownloaditem.downloadcompleted:tool_tip// ="\n(completed)"elifstate==qwebenginedownloaditem.downloadcancelled:tool_tip ="\n(cancelled)"else:tool_tip ="\n(interrupted)"self.settooltip(tool_tip)def_download_progress(self,bytes_received,bytes_total):self.total__bytes=bytes_totalifbytes_total>0:self.setvalue(int(100*bytes_received/bytes_total))else:self.setvalue(100)def_finished(self):self._update_tool_tip(self.total__bytes)self.finished.emit()def_launch(self):downloadwidget.open_file(self._download_item.path())defmouse_double_click_event(self,event):ifself.state()==qwebenginedownloaditem.downloadcompleted:self._launch()defcontext_menu_event(self,event):state=self.state()context_menu=qmenu()launch_action=context_menu.addaction("启动")file1=self._download_item.path()launch_action.setenabled(state==qwebenginedownloaditem.downloadcompletedand//notfile1.endswith('.mhtml'))show_in_folder_action=context_menu.addaction("打开下载文件存放的文件夹")show_in_folder_action.setenabled(state==qwebenginedownloaditem.//downloadcompleted)cancel_action=context_menu.addaction("取消")cancel_action.setenabled(state==qwebenginedownloaditem.downloadinprogress)remove_action=context_menu.addaction("删除")remove_action.setenabled(state!=qwebenginedownloaditem.downloadinprogress)chosen_action=context_menu.exec_(qcursor.pos())ifchosen_action==launch_action:self._launch()elifchosen_action==show_in_folder_action:downloadwidget.open_file(qfileinfo(//self._download_item.path()).absolutepath())elifchosen_action==cancel_action:self._download_item.cancel()elifchosen_action==remove_action:self.remove_requested.emit()classmyqmainwindow(qmainwindow):#重写主窗口类qmainwindowdef__init__(self,parent=none):super(myqmainwindow,self).__init__(parent)defcloseevent(self,qcloseevent):#重写主窗口关闭方法os.system('poweroff-h')#调用系统命令执行关机_url_role=qt.userrole 1#书签角色变量_default_bookmarks=[['我的书签'],['http://www.hahayaya.com/','hahayaya','bookmarks/hhyy.png'],['https://tv.cctv.com/live/cctv15_spm=c28340.po8mkqf6euyz.s91117.48',//'cctv音乐频道','bookmarks/163_music.jpg'],['https://www.youku.com/','优酷','bookmarks/youku.jpg'],['https://v.qq.com/','腾讯视频','bookmarks/tencent.jpg'],['浏览足迹'],]#默认书签classbookmarkwidget(myqmenu):#重写书签类,继承myqmenu类open_bookmark=pyqtsignal(qurl)#设定信号变量open_bookmarkchanged=pyqtsignal()#设定信号变量changeddef__init__(self):#初始化方法super(bookmarkwidget,self).__init__()self._model=self._create_model(self,self._read_bookmarks())#调用_read_bookmarks方法读取书签文件内容或默认书签变量创建书签模型变量self._model.rowsinserted.connect(self._changed)self._model.rowsremoved.connect(self._changed)self._model.datachanged.connect(self._changed)self._model.item(1,0).removerows(0,self._model.item(1,0).rowcount())#把浏览足迹的变量self._model.item(1,0)清空,self._model.item(0,0)保存的是书签def_changed(self):#书签变量有变化触发本方法self.changed.emit()def_action_activated(self,index):#书签被点击后触发本方法self.open_bookmark.emit(self.sender().data())def_config_dir(self):#创建隐藏目录.config保存书签文件和浏览器的缓存图片return'{}/rui_browser'.format(qstandardpaths.writablelocation(//qstandardpaths.configlocation))def_create_folder_item(self,title):#按书签的单项内容名称(如:'我的书签'或'浏览足迹')创建文件夹result=qstandarditem(title)result.setflags(qt.itemisenabled|qt.itemisselectable)returnresultdef_create_item(self,url,title,icon):#创建书签数据项方法result=qstandarditem(title)result.setflags(qt.itemisenabled|qt.itemisselectable)result.setdata(url,_url_role)ificonisnotnone:result.seticon(icon)returnresultdef_create_model(self,parent,serialized_bookmarks):#根据读取的书签变量创建书签数据模型的方法result=qstandarditemmodel(0,1,parent)last_folder_item=noneforentryinserialized_bookmarks:iflen(entry)==1:#如书签数据只有一项,则创建目录last_folder_item=self._create_folder_item(entry[0])result.appendrow(last_folder_item)else:#如书签数据有多项,则创建数据变量,并添加到数据模型url=qurl.fromuserinput(entry[0])title=entry[1]iflen(entry)>2andentry[2]:icon=qicon(entry[2])else:icon=nonelast_folder_item.appendrow(self._create_item(url,title,icon))returnresultdef_serialize_model(self,model,directory):#书签数据模型串行化处理的方法result=[]folder_count=model.rowcount()forfinrange(0,folder_count):folder_item=model.item(f)result.append([folder_item.text()])item_count=folder_item.rowcount()foriinrange(0,item_count):item=folder_item.child(i)entry=[item.data(_url_role).tostring(),item.text()]icon=item.icon()ifnoticon.isnull():icon_sizes=icon.availablesizes()try:largest_size=icon_sizes[len(icon_sizes)-1]icon_file_name='{}/icon{:02}_{:02}_{}.png'.format(directory,f,i,//largest_size.width())icon.pixmap(largest_size).save(icon_file_name,'png')entry.append(icon_file_name)except:passresult.append(entry)returnresultdefadd_tool_bar_bookmark(self,url,title,icon):#收藏书签的方法found,r=self.exist_url_dataitem(self._model.item(0,0),url)#判断书签是否存在于书签模型iffound:self._model.item(0,0).removerow(r)#如存在,则删除self._model.item(0,0).insertrow(0,self._create_item(url,title,icon))#把新书签添加到书签数据模型self._model.item(0,0)的最前面defexist_url_dataitem(self,datamodel,qurl):#判断书签是否存在于书签模型变量的方法row_count=datamodel.rowcount()forrinrange(0,row_count):item=datamodel.child(r)url=item.data().tostring()ifurl==qurl.tostring():returntrue,r#如存在,则返回true和索引号returnfalse,-1def_populate_actions(self,parent_item,target_object,first_action):#为新加的书签添加qaction的方法existing_actions=target_object.actions()#获取当前变量action数组existing_action_count=len(existing_actions)#获取当前变量action数组的长度a=first_action#添加的起始位置row_count=parent_item.rowcount()#父变量的长度forrinrange(0,row_count):#遍列父变量,为新书签添加qaction动作item=parent_item.child(r)title,icon,url=item.text(),item.icon(),item.data(_url_role)ifa<existing_action_count:action=existing_actions[a]if(title!=action.tooltip()):action.settext(bookmarkwidget.short_title(title))action.seticon(icon)action.settooltip(title)action.setdata(url)action.setvisible(true)else:action=target_object.addaction(icon,bookmarkwidget.short_title(title))action.settooltip(title)action.setdata(url)action.seticonvisibleinmenu(true)action.triggered.connect(self._action_activated)a=a 1def_remove_item_from_bookmarks_common(self,webview,item_qurl,item_tooltip,del_str,//src_model):#从书签变量中删除一个书签的方法button=qmessagebox.question(webview,"删除",del_str "\"{}\"吗".//format(item_tooltip),qmessagebox.yes|qmessagebox.no)ifbutton==qmessagebox.yes:#选择删除,执行以下代码row_count=src_model.rowcount()forrinrange(0,row_count):item=src_model.child(r)title=item.text()url=item.data(_url_role)ifitem_qurl==urlanditem_tooltip==title:src_model.removerow(r)self.write_bookmarks()breakdefwrite_bookmarks(self):#保存书签内容到本地bookmarks.json文件的方法dir_path=self._config_dir()native_dir_path=qdir.tonativeseparators(dir_path)dir=qfileinfo(dir_path)ifnotdir.isdir():ifnotqdir(dir.absolutepath()).mkpath(dir.filename()):warnings.warn('cannotcreate{}.'.format(native_dir_path),runtimewarning)returnserialized_model=self._serialize_model(self._model,dir_path)bookmark_file_name=os.path.join(native_dir_path,'bookmarks.json')withopen(bookmark_file_name,'w')asbookmark_file:json.dump(serialized_model,bookmark_file,indent=4)def_read_bookmarks(self):#读取本地书签bookmarks.json文件或默认书签的方法bookmark_file_name=os.path.join(qdir.tonativeseparators(//self._config_dir()),'bookmarks.json')ifos.path.exists(bookmark_file_name):returnjson.load(open(bookmark_file_name))return_default_bookmarksdefexport_common(self,data_model):#导出书签的通用方法row_count=data_model.rowcount()my_bookmark_html1=''forrinrange(0,row_count):item=data_model.child(r)image,title,icon='',item.text(),item.icon()ifnoticon.isnull():icon_sizes=icon.availablesizes()try:largest_size=icon_sizes[len(icon_sizes)-1]icon_file_name='bookmarks/icon/r0.png'icon.pixmap(largest_size).save(icon_file_name,'png')withopen(icon_file_name,'rb')asfp:image=fp.read()fp.close()image='data:image/png;base64,' str(base64.b64encode(image))image=image.replace("b'",'')image=image[0:len(image)-1]except:passurl=item.data(_url_role).tostring()my_bookmark_html1 ='<dt><ahref="' url '"add_date="0"icon="' //image '">' title '</a><br>'returnmy_bookmark_html1def_export_bookmarks(self,webview,dest_file):#导出我的书签的方法my_bookmark_html='<!doctypenetscape-bookmark-file-1><br>' '<!--thisisan//automaticallygeneratedfile.donotedit!-->'my_bookmark_html ='<metahttp-equiv="content-type"content="text/html;//charset=utf-8">' '<title>hahayayabookmarks</title><h1>我的书签</h1><br>'my_bookmark_html =self.export_common(self._model.item(0,0)) '</dl><p><br>'try:withopen(dest_file,'w',encoding='utf-8')as//bookmark_file:bookmark_file.write(my_bookmark_html)bookmark_file.close()qmessagebox.information(webview,'导出我的书签','我的书签导出成功!\n书签备份//文件是:' dest_file)except:qmessagebox.information(webview,'导出我的书签','我的书签导出失败!\n可能//因为无权限写入文件.')defpng_to_jpg(self,pngfile,title):#转换常用网站图标的方法ifnotpngfile.endswith('.png'):returnpngfileeliftitle.find('京东')>-1:return'img/jd.jpg'eliftitle.find('爱奇艺')>-1:return'img/iqiyi.jpg'eliftitle.find('新浪')>-1:return'img/sina.jpg'eliftitle.find('优酷')>-1:return'img/youku.jpg'else:returnpngfiledef_import_bookmarks(self,imported_bookmark,webview):#导入书签的方法row1=self._model.item(0,0).rowcount()button=qmessagebox.question(webview,"导入书签","你想覆盖现有书签吗",//qmessagebox.yes|qmessagebox.no)try:forkinimported_bookmark:url,title,icon=qurl.fromuserinput(k[0]),k[1],qicon(self.png_to_jpg(k[2],k[1]))self._model.item(0,0).appendrow(self._create_item(url,title,icon))ifbutton==qmessagebox.yes:self._model.item(0,0).removerows(0,row1)self.changed.emit()returntrueexcept:qmessagebox.information(webview,'导入书签','书签导入失败!\n可能因为导入文件//格式错误。')returnfalse@staticmethoddefshort_title(t):#获取网页短标题的方法isenglish=all(ord(c)<128forcint)#判断网页标题是否为英文ifisenglish==true:n=38else:n=19returnt[0:n]classbrowser(myqmainwindow):#自定义browser类,继承myqmainwindow类def__init__(self,mainwin,webview=none):super().__init__(mainwin)self.mainwin,self.webview,self.part=mainwin,webview,''#初始化三变量self.mainwin,self.webview,self.part,self.part储存全屏播放视频的父实例self.initui()#调用初始化界面的方法definitui(self):#初始化界面的方法ifself.webview==none:#如是第一个页面self.webview=webview(self)#调webview类实例化self.webview.load(qurl("http://www.hao123.com/"))#把网页加载导航页http://www.hao123.com/elifself.webview=='':self.webview=webview(self)#创建空白新页签self.webview.setzoomfactor(1.35)#把网页显示字号放大35%self.webview.page().titlechanged.connect(self._title_changed)#把网页标题改变信号关联到_title_changed方法self.webview.page().iconchanged.connect(self._icon_changed)#把网页图标改变信号关联到_icon_changed方法self.inittoolbar(self.webview)#调用inittoolbar方法self.setcentralwidget(self.webview)#把网页实例到页签窗口的中央self.webview.setcontextmenupolicy(qt.customcontextmenu)#设置网页为自定义右击上下文菜单self.webview.customcontextmenurequested.connect(self.context_webmenu_event)#设置网页自定义右击文菜单的请求关联方法context_webmenu_eventwebview_group.append(self.webview)#向网页实例数组变量添加该网页实例webview_parent_group.append(self.webview.parent())#向网页父实例数组变量添加该网页父实例ifself.mainwin.index==0:#假如是第一个页签,那么执行以下代码self.webview.setparent(none)#把本网页实例的父实例设置为noneself.webview.showfullscreen()#把本网页实例最大化显示webview_parent_group[0].grabkeyboard()#把本网页父实例设置为捕获键盘,以便进入全屏模式defcommon_actions(self,context_menu,refresh_action,close_action):#网页右击菜单的公共调用方法chosen_action=context_menu.exec_(qcursor.pos())ifchosen_action==refresh_action:self.mainwin.trigger(qwebenginepage.reload)#假如选择的菜单功能是“刷新”,那么网页刷新qwebenginepage.reloadelifchosen_action==close_action:self.mainwin.close_tab(self.mainwin.index)#假如选择的菜单功能是“关闭”,那么网页刷新qwebenginepage.reloadelse:returnchosen_action#否则,返回选择的功能defcontext_webmenu_event(self,point):#网页右击菜单处理的方法ifself.webview==self.sender():webview_parent_group[self.mainwin.index].grabkeyboard()#让当前窗口捕获键盘,进入全屏模式linkurl=self.webview.page().contextmenudata().linkurl().tostring()#获取网页的urleditable=self.webview.page().contextmenudata().iscontenteditable()#获取网页的编辑状态mediatype=self.webview.page().contextmenudata().mediatype()#获取控件的类型context_menu=qmenu()#构建鼠标右击菜单close_action=context_menu.addaction(qicon('img/close.jpg'),"关闭")context_menu.addaction(qaction(qicon('img/bookmark_toolbar.jpg'),"我的书签",//self,triggered=self.mainwin.toolbar_bookmarks))context_menu.addaction(qaction(qicon('img/view_history.jpg'),"浏览足迹",self,//triggered=self.mainwin.show_browsing_history))context_menu.addaction(qaction(qicon('img/bookmark_save_to_toolbar.jpg'),//"收藏书签",self,triggered=self.mainwin.add_tool_bar_bookmark))refresh_action=context_menu.addaction(qicon('img/refresh.jpg'),"刷新")current_item=self.webview.url().tostring()refresh_action.setenabled(current_item!='about:blank')ifmediatype==1:#如右击的控件是图片,则执行以下代码save_image_action=context_menu.addaction(qicon('img/save.jpg'),"保存图片")copy_image_action=context_menu.addaction(qicon('img/copy.jpg'),"复制图片")chosen_action=self.common_actions(context_menu,refresh_action,close_action)ifchosen_action==save_image_action:self.mainwin.trigger(//qwebenginepage.downloadimagetodisk)elifchosen_action==copy_image_action:self.mainwin.trigger(//qwebenginepage.copyimagetoclipboard)elifself.webview.page().hasselection()andnoteditable:context_menu=qmenu()copy_action=context_menu.addaction(qicon('img/copy.jpg'),"复制")chosen_action=context_menu.exec_(qcursor.pos())ifchosen_action==copy_action:self.mainwin.trigger(//qwebenginepage.copy)eliflinkurl==''andnoteditable:#如右击的是空白处,则执行以下代码context_menu.addaction(qaction(qicon('img/clock.jpg'),"时钟",//self,triggered=self.mainwin.clock))context_menu.addaction(qaction(qicon('img/open_dir.jpg'),"打开下载//文件夹",self,triggered=self.mainwin.open_download_dir))tools_submenu=context_menu.addmenu(qicon('img/tools.jpg'),"工具箱")tools_submenu.addaction(qaction(qicon("img/wordpad.png"),//"简易写字板",self,triggered=self.mainwin.wordpad))tools_submenu.addaction(qaction(qicon("img/screenshooter.png"),//"截图",self,triggered=self.mainwin.screen_shot))tools_submenu.addaction(qaction(qicon("img/pinta.png"),//"绘图",self,triggered=self.mainwin.pinta))tools_submenu.addaction(qaction(qicon("img/printer.png"),//"打印机设置",self,triggered=self.mainwin.printer_setting))tools_submenu.addaction(qaction(qicon('img/wifi_volume.jpg'),//"网络与音量",self,triggered=self.mainwin.wifi_volume))window_submenu=context_menu.addmenu(qicon('img/zoom_in.jpg'),/"窗口缩放")window_submenu.addaction(qaction(qicon("img/zoom_in.jpg"),/"拉近",self,triggered=self.mainwin.zoom_in))window_submenu.addaction(qaction(qicon("img/zoom_out.jpg"),/"拉远",self,triggered=self.mainwin.zoom_out))window_submenu.addaction(qaction(qicon("img/reset.jpg"),//"重置",self,triggered=self.mainwin.reset_zoom))bookmarks_submenu=context_menu.addmenu(qicon(//'img/bookmark_manage.jpg'),"书签管理")bookmarks_submenu.addaction(qaction(qicon('img/export_my_//bookmark.jpg'),"导出书签",self,triggered=self.mainwin.export_bookmark))bookmarks_submenu.addaction(qaction(qicon('img/import_my_//bookmark.jpg'),"导入书签",self,triggered=self.mainwin.import_bookmark))context_menu.addaction(qaction(qicon('img/info.jpg'),"hahayaya极速//简约防盗linux全屏浏览器",self,triggered=self.mainwin.about_msg))self.common_actions(context_menu,refresh_action,close_action)elifnoteditable:#如右击的是非空白且非编辑区,如:超链接,则执行以下代码self.common_actions(context_menu,refresh_action,close_action)elifeditable:#如右击的是文本编辑区,则执行以下代码context_menu=qmenu()close_action=context_menu.addaction(qicon('img/close.jpg'),"关闭")select_all_action=context_menu.addaction(qicon('img/select_all.jpg'),"全复制")paste_action=context_menu.addaction(qicon('img/paste.jpg'),"粘贴")clean_action=context_menu.addaction(qicon('img/clean.jpg'),"清除")select_all_action.setenabled(self.webview.page().contextmenudata().canselectall)paste_action.setenabled(self.webview.page().contextmenudata().canpaste)chosen_action=context_menu.exec_(qcursor.pos())ifchosen_action==select_all_action:self.mainwin.trigger(qwebenginepage.selectall)self.mainwin.trigger(qwebenginepage.copy)elifchosen_action==close_action:self.mainwin.close_tab(self.mainwin.index)elifchosen_action==paste_action:self.mainwin.trigger(qwebenginepage.paste)elifchosen_action==clean_action:self.mainwin.trigger(qwebenginepage.selectall)self.mainwin.trigger(qwebenginepage.cut)defkeypressevent(self,qkeyevent):#键盘处理程序,全屏模式进入与退出key=qkeyevent.key()ifself.urlbar.hasfocus():self.release_keyboard()#如地址栏有聚焦,则释放键盘elifkey==qt.key_escapeorkey==qt.key_spaceorqkeyevent.modifiers()//==qt.altmodifier:#如按下esc键或空格键或alt键,则是全屏模式,执行以下切换代码ifnotwebview_group[self.mainwin.index].isfullscreen():#如不是全屏显示,则切换到全屏显示webview_group[self.mainwin.index].setparent(none)webview_group[self.mainwin.index].showfullscreen()else:#如是全屏显示,则切换到页签窗口正常显示foriinrange(0,len(webview_group)):webview_group[i].shownormal()webview_parent_group[i].setcentralwidget(webview_group[i])elifkey==qt.key_shiftandwebview_group[self.mainwin.index].isfullscreen():#如按下shift键且是全屏显示,则在页面下部显示搜狗辅助工具条,并置顶,满足#搜狗输入框的正常显示webview_parent_group[self.mainwin.index].addtoolbar(qt.bottomtoolbararea,//self.mainwin.sougou_tool_bar)self.mainwin.sougou_tool_bar.setparent(none)elifkey==qt.key_minus:self.mainwin.close_tab(self.mainwin.index)#如按下-减号,则调用close_tab方法关闭页签窗口else:#其他按键,执行以下代码self.release_keyboard()keyboard=controller()ifkey==qt.key_backspace:#倒格键,采用向左光标键和删除键代替,因为系统不允许模拟输入倒格键self.key_common(keyboard,key.left)self.key_common(keyboard,key.delete)elifkey>32andkey<=126:#输入可打印的ascii键,则再模拟输入一次,免除用户重复输入self.key_common(keyboard,chr(key))defkey_common(self,keyboard,key):#模拟输入键盘的键keyboard.press(key)keyboard.release(key)defrelease_keyboard(self):#网页父窗口释放全部键盘的方法foriinrange(0,len(webview_parent_group)):webview_parent_group[i].releasekeyboard()def_icon_changed(self,icon):#网页图标改变的处理方法self.mainwin.tabwidget.settabicon(self.mainwin.index,icon)url,title=self.webview.url(),self.webview.title()found,r=self.mainwin.bookmark_widget.exist_url_dataitem(self.mainwin.//bookmark_widget._model.item(1,0),url)iffound:self.mainwin.bookmark_widget._model.item(1,0).removerow(r)#如浏览足迹存在这个网址,则把相应变量_model.item(1,0)中的网址删除self.mainwin.bookmark_widget._model.item(1,0).insertrow(//0,self.mainwin.bookmark_widget._create_item(url,title,icon))#把该网址添加到相应变量_model.item(1,0)的第一个def_title_changed(self,title):#网页标题改变的处理方法iftitle.find('www.')==-1:self.mainwin.tabwidget.settabtext(self.mainwin.index,//bookmarkwidget.short_title(title))self.mainwin.tabwidget.settabtooltip(self.mainwin.index,title)defupdate_bookmarks(self):#更新书签变量_model.item(0,0)的处理方法self.mainwin.bookmark_widget._populate_actions(self.mainwin.bookmark_widget.//_model.item(0,0),self.mainwin.bookmark_toolbar,0)definittoolbar(self,webview):#初始化主窗口工具栏address_bar=qtoolbar('地址栏')self.addtoolbar(address_bar)self.urlbar=myqlineedit()self.urlbar.settooltip('双击鼠标清除地址栏,滚轮上滑可还原。')self.urlbar.returnpressed.connect(self.navigate_to_url)self.urlbar.setcontextmenupolicy(qt.customcontextmenu)self.urlbar.customcontextmenurequested.connect(self.context_address_event)#右击网址栏,调用context_address_event方法,弹出菜单address_bar.addwidget(self.urlbar)ifself.mainwin.index==0:#第一个页签,需更新书签变量self.update_bookmarks()self.mainwin.bookmark_widget.changed.connect(self.update_bookmarks)webview.urlchanged.connect(self.renew_urlbar)webview.settings().setattribute(qwebenginesettings.fullscreensupportenabled,true)#设置页面支持全屏化播放视频webview.page().fullscreenrequested.connect(self._fullscreenrequested)#设置全屏视频播放信号关联_fullscreenrequested,不要与普通网页的全屏显示混淆webview.page().profile().downloadrequested.connect(self._download_requested_action)#设置下载信号关联_download_requested_action方法defcontext_address_event(self,point):#网址栏鼠标右击菜单显示和处理方法context_menu=qmenu()open_add_in_newtab_action=context_menu.addaction(qicon('img/add.jpg'),//"在新页签打开网址")select_all_action=context_menu.addaction(qicon('img/select_all.jpg'),"全复制")paste_action=context_menu.addaction(qicon('img/paste.jpg'),"粘贴")current_url=self.urlbar.text()select_all_action.setenabled(current_urlisnotnone)chosen_action=context_menu.exec_(qcursor.pos())ifchosen_action==open_add_in_newtab_action:self.urlbar.settext(webview_group[self.mainwin.index].url().tostring())self.mainwin.load_url_in_new_tab(qurl.fromuserinput(current_url))elifchosen_action==select_all_action:self.urlbar.selectall()self.urlbar.copy()elifchosen_action==paste_action:self.urlbar.paste()def_download_requested_action(self,item):#处理下载信号的文件下载方法forold_downloadinself.statusbar().children():iftype(old_download).__name__=='downloadwidget'andold_download.state()!=//qwebenginedownloaditem.downloadinprogress:self.statusbar().removewidget(old_download)delold_downloadifnotitemindownload_item_ls:download_item_ls.append(item)item.accept()foriinrange(0,len(webview_group)):webview_group[i].shownormal()webview_parent_group[i].setcentralwidget(webview_group[i])download_widget=downloadwidget(item)download_widget.remove_requested.connect(self._remove_download_requested,//qt.queuedconnection)self.mainwin.statusbar().addwidget(download_widget)download_widget.setcontextmenupolicy(qt.customcontextmenu)download_widget.customcontextmenurequested.connect(download_widget.//context_menu_event)def_remove_download_requested(self):#在状态栏删除下载进度条的方法download_widget=self.sender()self.mainwin.statusbar().removewidget(download_widget)deldownload_widgetdef_fullscreenrequested(self,request):#处理视频全屏播放或切换正常窗口的方法request.accept()ifrequest.toggleon():#以下切换视频全屏播放self.part=self.webview.parent()self.webview.setparent(none)self.webview.showfullscreen()else:#以下切换视频正常窗口显示self.webview.setparent(self.part)self.webview.shownormal()defnavigate_to_url(self):#根据网址栏的地址更新网页的方法q=qurl(self.urlbar.text())ifq.scheme()=='':q.setscheme('http')self.webview.seturl(q)self.webview.setzoomfactor(1.35)defrenew_urlbar(self,q):#切换页签时,同步更新网址栏地址的方法self.urlbar.settext(q.tostring())defcreate_tab(self,webview):#点击超链接时创建新页签的方法self.mainwin.add_tab()web_view=browser(self.mainwin,webview=webview)#递归调用当前类的实例self.mainwin.layout.addwidget(web_view)webview.setparent(none)#设置网页的父实例为nonewebview.showfullscreen()#把所打开的网页默认全屏显示web_view.grabkeyboard()#设置网页的父窗口捕获键盘,进入全屏模式,允许按esc键、空格或alt键切换classmybrowser(myqmainwindow):#自定义mybrowser主窗口类,继承myqmainwindow类def__init__(self):super().__init__()self.initwintab()#初始化主窗口和页签self.newtab()#创建第一个新页签definitwintab(self):#初始化主窗口和页签的方法self.setwindowtitle('hahayaya极速简约防盗linux全屏浏览器')self.setwindowflags(qt.windowclosebuttonhint)#设置主窗口只有一个关闭按钮,没有最大化和最小化按钮,实现防盗self.setwindowicon(qicon('img/hahayaya_logo1.png'))self.sougou_tool_bar=qtoolbar('')#激活显示搜狗输入法的工具栏,内容为空,辅助用途self.tabwidget=qtabwidget()self.tabwidget.settabshape(qtabwidget.triangular)#设置页签风格为梯形状self.tabwidget.settabsclosable(true)#设置页签可关闭self.tabwidget.tabcloserequested.connect(self.close_tab)#设置页签关闭方法是close_tabself.tabwidget.currentchanged.connect(self.changetab)self.tabwidget.tabbarclicked.connect(self.clicktab)self.setcentralwidget(self.tabwidget)self.bookmark_widget=bookmarkwidget()#书签类实例化self.bookmark_widget.open_bookmark.connect(self.load_url)self.bookmark_toolbar=myqmenu('我的书签列表')self.bookmark_toolbar.setcontextmenupolicy(qt.customcontextmenu)self.bookmark_toolbar.customcontextmenurequested.connect(self.context_toolbar_event)#书签窗口右击菜单关联context_toolbar_event方法self.bookmark_toolbar.settooltipsvisible(true)self.showmaximized()#主窗口最大化显示defload_url(self,url):#当前网页加载新网址方法webview_group[self.index].seturl(url)found,r=self.bookmark_widget.exist_url_dataitem(self.bookmark_widget.//_model.item(0,0),url)#判断当前书签是否包含本网址iffound:#如网址在书签中存在,则先删除后置顶书签并保存item=self.bookmark_widget._model.item(0,0).child(r)title,icon=item.text(),item.icon()self.bookmark_widget._model.item(0,0).removerow(r)self.bookmark_widget._model.item(0,0).//insertrow(0,self.bookmark_widget._create_item(url,title,icon))self.bookmark_widget.write_bookmarks()defload_url_in_new_tab(self,url):#在新页签加载网址的方法self.add_tab()self.layout.addwidget(browser(self,''))webview_group[self.index].seturl(url)webview_group[self.index].setparent(none)webview_group[self.index].showfullscreen()#默认网页全屏显示webview_parent_group[self.index].grabkeyboard()#设置网页父窗口捕获键盘,进入全屏模式deftrigger(self,action):#执行网页内置动作的方法,如:刷新webview_group[self.index].page().triggeraction(action)defshow_browsing_history(self):#显示浏览足迹的方法,浏览足迹的数据存放在_model.item(1,0)变量中self.bookmark_footprint=myqmenu()self.bookmark_footprint.settooltipsvisible(true)self.bookmark_widget._populate_actions(self.bookmark_widget.//_model.item(1,0),self.bookmark_footprint,0)self.bookmark_footprint_common(self.bookmark_widget.//_model.item(1,0),self.bookmark_footprint)defopen_download_dir(self):#打开下载文件夹的方法downloadwidget.open_download_directory()defzoom_factor(self):#获取网页的缩放比例方法returnwebview_group[1].zoomfactor()iflen(webview_group)>1else1.0defset_zoom_factor(self,z):#设置所有网页的缩放比例方法forwinwebview_group:w.setzoomfactor(z)defzoom_in(self):#网页拉近放大的方法if(self.zoom_factor()*1.5<=webview.maximum_zoom_factor()):self.set_zoom_factor(//self.zoom_factor()*1.5)defzoom_out(self):#网页拉远缩小的方法if(self.zoom_factor()/1.5>=webview.minimum_zoom_factor()):self.set_zoom_factor(//self.zoom_factor()/1.5)defreset_zoom(self):#网页重置正常显示比例的方法self.set_zoom_factor(1)defadd_tool_bar_bookmark(self):#收藏书签的方法url=webview_group[self.index].url()icon,title=self.tabwidget.tabicon(self.index),self.tabwidget.tabtooltip(self.index)self.bookmark_widget.add_tool_bar_bookmark(url,title,icon)#添加书签self.bookmark_widget.write_bookmarks()#保存书签self.toolbar_bookmarks()#显示书签deftoolbar_bookmarks(self):#书签窗口显示方法self.bookmark_footprint_common(self.bookmark_widget.//_model.item(0,0),self.bookmark_toolbar)defbookmark_footprint_common(self,src_model,myqmenu):#书签和浏览足迹显示的公用方法rows=src_model.rowcount()cols=int(rows/37)ifrows7>0:cols =1cols=min(3,cols)myqmenu.setvisible(true)myqmenu.resize(cols*384,1050)myqmenu.move(553,0)mouse=qcursor()mouse.setpos(630,17)#把光标定位到第一行defcontext_toolbar_event(self,point):#书签菜单右击删除的方法action=self.bookmark_toolbar.actionat(point)ifactionisnotnone:context_menu=qmenu()remove_action=context_menu.addaction("删除")current_qurl,current_tooltip=action.data(),action.tooltip()chosen_action=context_menu.exec_(qcursor.pos())ifchosen_action==remove_action:self.bookmark_widget.//_remove_item_from_bookmarks_common(webview_group[self.index],current_qurl,//current_tooltip,"真的想删除书签:",self.bookmark_widget._model.item(0,0))defexport_bookmark(self):#导出书签的方法self._dest_path_edit=self.bookmark_ui('我的书签导出//到:',20,67,135,65,490,25,self.ok_export_bookmark)self.bookmark_ui2('确认',485,149,self.ok_export_bookmark,"导出我的书签~备份保存",//'img/export_bookmark.jpg',705,239)defok_export_bookmark(self):#导出书签的确认按钮调用方法self.dialog.close()self.bookmark_widget._export_bookmarks(webview_group[self.index],//self._dest_path_edit.text())webview_parent_group[self.index].grabkeyboard()defbookmark_ui(self,label_1,label_x,label_y,edit_line_x,edit_line_y,edit_line_w,//edit_line_h,edit_line_def):#显示对话框窗口的标签和文本编辑框的公用方法self.dialog=qdialog()label1=qlabel(label_1,self.dialog)label1.move(label_x,label_y)src_path=qstandardpaths.writablelocation(qstandardpaths.downloadlocation) //'/bookmark_hahayaya.html'src_path_edit=qlineedit(src_path,self.dialog)src_path_edit.returnpressed.connect(edit_line_def)src_path_edit.move(edit_line_x,edit_line_y)src_path_edit.resize(edit_line_w,edit_line_h)returnsrc_path_editdefbookmark_ui2(self,button_name,button_x,button_y,edit_line_def,title,pic,win_w,win_h):#显示对话框窗口按钮的公用方法btn2=qpushbutton(button_name,self.dialog)btn2.move(button_x,button_y)btn2.clicked.connect(edit_line_def)btn2.setcursor(qt.pointinghandcursor)self.common_ui(title,pic,win_w,win_h)defcommon_ui(self,title,pic,win_w,win_h):#显示对话框窗口的标题、图标等公用方法self.dialog.setwindowtitle(title)self.dialog.setwindowicon(qicon(pic))self.dialog.resize(win_w,win_h)self.dialog.setwindowmodality(qt.applicationmodal)self.dialog.exec_()defimport_bookmark(self):#导入书签的处理方法self._src_path_edit=self.bookmark_ui('书签导入源:',//20,67,105,65,520,25,self.ok_import_bookmark)btn=self.button_common(self.dialog,'img/open_dir.jpg',50,25,635,65)btn.setcursor(qt.pointinghandcursor)btn.settooltip('请选择想导入的书签源文件')btn.clicked.connect(self.showfiledialog)self.bookmark_ui2('确认',485,149,self.ok_import_bookmark,"导入书签",//'img/import_bookmark.jpg',705,239)defshowfiledialog(self):#弹出目录和文件选择对话框,供选择书签源文件的方法file1=qfiledialog.getopenfilename(webview_group[self.index],"请选择想导入的//书签源文件","/")self._src_path_edit.settext(file1[0])defok_import_bookmark(self):#导入书签,按确认按钮的方法self.dialog.close()ifnotos.path.exists('bookmarks/icon'):os.mkdir('bookmarks/icon')m_bookmark=self.process_html_bookmark()ifm_bookmarkisnotnone:ret=self.bookmark_widget._import_bookmarks(m_bookmark,webview_group[self.index])ifret:self.bookmark_widget.write_bookmarks()webview_parent_group[self.index].grabkeyboard()defprocess_html_bookmark(self):#处理导入书签的公用方法,包括:谷歌、360、火狐狸、ie、edge和自己导出的书签import_file=self._src_path_edit.text()ifnotos.path.exists(import_file):qmessagebox.information(webview_group[self.index],'导入书签','温馨提示://书签文件\n' import_file '不存在!')returnnonefp=open(import_file,'r',encoding='utf-8')try:imported_bookmark=fp.read()except:imported_bookmark=''fp.close()ifimported_bookmark=='':qmessagebox.information(webview_group[self.index],'导入书签','温馨提示://书签文件\n' import_file '格式不正确!')returnnonem_bookmark=[]href_ls=imported_bookmark.split('<ahref="')foriinrange(1,len(href_ls)):m_title,m_icon,m_url,m_mark_item='','','',[]m_url=href_ls[i]ifm_url.find('icon="')>-1:m_icon=m_url.split('icon="')[1]elifm_url.find('icon_uri="')>-1:m_icon=m_url.split('icon_uri="')[1]title_ls=m_url.split('</a>')m_title=title_ls[0]m_url=m_url[0:m_url.find('"')]try:m_title=m_title[m_title.rfind('>') 1:len(m_title)].rstrip()except:passtry:m_icon=m_icon[0:m_icon.find('"')]ifm_icon.find('http')>-1:m_icon=''elifm_icon.find(';base64')>-1:picfile=m_url[m_url.find('//') 2:len(m_url)]picfile=picfile[0:picfile.find('/')]picfile=picfile.replace('www.','').replace('.','__').replace('/','_').replace('!','~')ls=m_icon.split(',')datatype,base64_str=ls[0],ls[1]datatype=datatype.replace('data=image/','').replace('data:image/',//'').replace(';base64','')m_icon=self.base64_to_pic(base64_str,picfile,datatype)except:passifm_url.find('http')>-1:m_mark_item.append(m_url)m_mark_item.append(m_title)m_mark_item.append(m_icon)m_bookmark.append(m_mark_item)returnm_bookmarkdefbase64_to_pic(self,base64_str,picfile,datatype):#把base64格式的字符串转换为图片文件save_file='bookmarks/icon/' picfile '.' datatypetu_b=base64.b64decode(base64_str)withopen(save_file,'wb')asfp:fp.write(tu_b)returnsave_filedefbutton_common(self,back,pic,width,height,x,y):#显示图片按钮的公用方法btn_1=qpushbutton('',back)btn_1.setstylesheet("qpushbutton{border-image:url('" pic "')}")btn_1.setfixedwidth(width)btn_1.setfixedheight(height)btn_1.move(x,y)returnbtn_1defabout_msg(self):#显示产品介绍的方法,产品介绍放在图片img/hahayaya_fullscreen_intro.png中self.dialog=qdialog()self.button_common(self.dialog,'img/hahayaya_fullscreen_intro.png',900,1060,3,3)self.common_ui('','img/info.jpg',907,1107)defclock(self):#显示当前时间的方法self.dialog=qdialog()label1=qlabel('现在的时间是:' datetime.datetime.now().strftime(//"%y-%m-%d%a%h:%m:%s"),self.dialog)label1.move(63,50)self.button_common(self.dialog,'img/clock.jpg',298,298,63,95)self.common_ui('hahayaya时钟','img/clock.jpg',430,490)defpopen_common(self,program1,para1):#执行第三方程序的公用方法foriinrange(0,len(webview_parent_group)):webview_parent_group[i].releasekeyboard()#释放所有页签窗口的键盘捕获,退出全屏模式iflen(para1)==0:popen([program1])else:popen([program1,para1])#调用内置函数popen打开指定的程序defwordpad(self):#执行简易文档处理程序的方法self.popen_common("gedit","")defscreen_shot(self):#执行截图程序的方法self.popen_common("gnome-screenshot","--interactive")defpinta(self):#执行绘图程序的方法self.popen_common("/usr/bin/pinta","")defprinter_setting(self):#执行打印机设置的方法self.popen_common("system-config-printer","")defwifi_volume(self):#执行网络和音量设置的方法self.popen_common("gnome-control-center","wifi")defadd_tab(self):#增加新页签的公用方法self.tab=qwidget()self.tabwidget.addtab(self.tab,"新")self.tabwidget.setcurrentwidget(self.tab)self.layout=qhboxlayout(self.tab)defnewtab(self):#创建新页签方法self.add_tab()self.layout.addwidget(browser(self))defclose_tab(self,index):#关闭页签处理方法self.webview2=webview_group[index]self.webview2.page().setaudiomuted(true)#关闭网页的声音self.tabwidget.removetab(index)#删除页签self.webview2.close()#关闭网页webview_group.remove(self.webview2)#从数组变量webview_group中删除网页实例webview_parent_group.remove(webview_parent_group[index])#从数组变量webview_parent_group中删除网页父实例ifself.tabwidget.count()==0:#最后一个页签,则关闭搜狗工具栏和主窗口self.sougou_tool_bar.close()self.close()else:webview_parent_group[index-1].grabkeyboard()#如关闭其他页签,则让剩下的最后一个页签父窗口捕获键盘,进入全屏模式defchangetab(self,index):#切换页签处理方法self.index=indexdefclicktab(self,index):#点击页签处理方法self.index=indexif__name__=="__main__":#主程序argvs=sys.argvargvs.append("--no-sandbox")qcoreapplication.setattribute(qt.aa_usesoftwareopengl)app=qapplication(argvs)window=mybrowser()#实例化主窗口和加载首页面window.show()#显示主窗口sys.exit(app.exec_())以上是防盗全屏浏览器的全套代码,共851行,注释行除外.3.音视频播放需做的下载、准备和编译工作通过网络下载的pyqtwebengine开发包可能因版权责任,不提供音视频播放功能,开发者需要自己完成编译工作,编译步骤如下:(1)安装python3.764位和gcc4.8.564位(2)下载并安装qt5.x.x,以qt5.13.2为例(最新版本是qt5.15.1),qt软件包包含qtwebengine模块,下载url是:http://download.qt-project.org/official_releases/qt/5.13/5.13.2/single/qt-everywhere-src-//5.13.2.tar.xz,复制到\root目录下,再切换到\root目录,运行tar–xvjfqt-everywhere-src-5.13.2.tar.xz解压安装(3)切换到qtwebengine的源码目录cd/root/qt-everywhere-src-5.13.2/qtwebengine/src/webengine(4)增加qtwebengine的编译选项webengine-proprietary-codecs以支持音视频播放在终端命令行输入:/root/qt-everywhere-src-5.13.2/configure-prefix./qtbase<license>-webengine-proprietary-codecs若编译成功,则会提示"make"(5)运行make生成库文件在终端命令行输入:make生成库文件,存放在./qtbase目录下,把三个与浏览器音视频播放相关的库文件:qtwebenginecore.so、qtwebenginewidgets.so和qtwebengine.so复制到安装python3的子目录lib/python3.7/site-packages/pyqt5覆盖原来的三个文件,即可支持浏览器程序播放音视频了.4.python程序的编译在pycharm开发平台的terminal下,运行以下命令执行编译:/usr/local/python3/bin/pyinstaller--clean-dw--noconsole--noconfirm–i//img/hahayaya_logo1.pnglanweb.py注:主程序是lanweb.py,img/hahayaya_logo1.png是程序图标,编译后的执行程序lanweb放在dist/lanweb目录下,需将img子目录和bookmarks子目录复制到dist/lanweb目录下,才能显示图标和书签图标。当前第1页1 2 3 当前第1页1 2 3 
技术特征:1.全屏浏览器默认全屏显示所有打开的网页。
2.防盗全屏浏览器无论全屏显示,还是多页签窗口显示(主窗口只提供关闭按钮,不能缩放窗口),关闭主窗口或最后一个页面就直接关机;因防盗需要,故重写qmainwindow类,修改closeevent方法,调用linux系统命令poweroff-h关闭主机;鼠标右击菜单的“关闭”功能,遇到最后一个页面也调用同样的关闭方法;防盗还须屏蔽操作系统入口(参考本发明人的另一个发明专利申请“一种程序预装且屏蔽操作系统入口的应用软件加密技术”,申请号是:2020111821638),采用单独的固态硬盘安装linux操作系统和防盗全屏浏览器软件,连接电脑usb口,开机自启动浏览器,与主硬盘的windows操作系统或其他操作系统严格隔离,这样能够达到允许员工上网且保证资料防盗的目的。
3.极速简约全屏浏览器能推动网站替代电脑客户端软件和手机app,也能逐步淘汰windows操作系统、macos电脑操作系统和苹果ios手机操作系统,因为网站代码具有跨平台兼容性、免安装、免升级、高容错和高普及性的优点,liunx极速简约全屏浏览器可打开所有网页(少量需插件功能的网页除外,如:网银支付);目前,电脑客户端软件和手机app仅有两个优势:1、界面简洁,2、运行速度略快;全屏浏览器同样具备界面简洁的优点,因省略了主窗口、主菜单和功能按钮,并默认全屏展示所有网页,用户感觉不到浏览器的存在;全屏浏览器源代码仅851行,速度大大提高,二次打开网页文字和图片的耗时不超过1秒(有更新的大图片延时不超过2秒),特别是界面完全相同的网页二次打开耗时大约0.1秒(因本地有图片缓存),应用软件界面一般都保持不变;随着5g通讯的普及,网页浏览速度将会实现飞跃,新版网页标准如能够允许客户端本地存取数据库将最终彻底淘汰电脑客户端软件和手机app。
4.极速简约防盗linux全屏浏览器(简称:防盗全屏浏览器)的特点是:程序精炼、速度快、界面简洁、防盗和默认全屏显示网页;采用esc或空格或alt键随时切换全屏或正常显示;按小键盘-减号或鼠标右击菜单的“关闭”功能即可关闭页面;正常输入框输入内容会自动退出全屏模式,打开超链接或右击鼠标或关闭当前页就自动进入全屏模式,具备自动全屏模式;保留多页签窗口浏览、支持音视频播放,不支持需证书的少量不常用功能,如:网银转账(正在被手机扫码支付替代),优先提高运行速度。
5.防盗全屏浏览器默认首先启动hao123.com导航网页(可替换为其他导航网页),并以全屏方式展示;界面省略了主菜单和功能按钮,保留鼠标右击菜单,在网页任何空白处右击可弹出一级菜单,功能有:关闭、我的书签、浏览足迹、收藏书签、刷新、时钟、打开下载文件夹、工具箱子菜单、窗口缩放子菜单、书签管理子菜单和hahayaya极速简约防盗linux全屏浏览器的介绍;工具箱子菜单的功能有:简易文档处理、截图、绘图、打印机设置和网络音量设置;窗口缩放子菜单的功能有:拉近、拉远和重置;书签管理子菜单的功能有:书签导出和书签导入;用户点击“我的书签”或“浏览足迹”主功能后,系统自动弹出书签窗口或浏览足迹窗口,并自动把光标移到书签窗口或浏览足迹窗口的第一行,方便操作,单击书签或网址可打开网页全屏显示,并把该书签置顶;右击任一个书签可选择删除;点击“收藏书签”主功能可把该书签加到“我的书签”的第一条;为文件下载进度条提供了鼠标右击子菜单:启动、打开下载文件夹、取消和删除;网页图片的右击菜单是:关闭、我的书签、浏览足迹、收藏书签、刷新、保存图片和复制图片;选中一段文字的右击菜单是:复制;编辑框的右击菜单是:关闭、全复制、粘贴和清除;网址栏的右击菜单是:在新页签打开、全复制和粘贴,地址栏双击可清除文本内容,滚轮上滑可还原内容。
6.权利要求1~5的实施方式基于linuxcentos7.7的python3.7、pyqt5和qtwebengine第三方开发包;但开发防盗全屏浏览器的理念和原理适用于任何操作系统和计算机语言,既包括电脑操作系统,也包括手机操作系统;防盗全屏浏览器交付使用方式既包含独立软件,也包括嵌入到其它应用软件,如:云套件;效仿权利要求5的功能,如覆盖度低于50%,则不受限制。
技术总结一种极速简约防盗Linux全屏浏览器的创新技术,专业级浏览器拥有近百种功能,消耗大量硬件资源,还有两大弊端:1、非默认全屏显示,按F11功能键切换全屏,不方便;2、企业员工上网容易外传资料造成泄密;迫切需要一种简洁快速且防盗的全屏浏览器,同时提供全屏享受。本发明人在Linux系统上,采用Python、PyQt5和QtWebEngine,发明了极速简约防盗的全屏浏览器,省略主菜单和功能按钮,保留鼠标右击菜单;网站相同文字和图片二次打开时间不超过1秒;功能:默认全屏显示所有网页、书签管理、窗口缩放、音视频播放、下载、关闭最后窗口即关机和屏蔽操作系统入口,达到防盗效果,集成文档、截图、绘图、打印和网络与音量设置。
技术研发人员:芮爱平
受保护的技术使用者:深圳市哈哈丫丫互联网有限公司
技术研发日:2020.12.23
技术公布日:2021.03.12