一种通用极简html超文本书签导入与导出的绿色程序的制作方法

文档序号:24378867发布日期:2021-03-23 11:13阅读:140来源:国知局
浏览器书签管理的极简技术。
背景技术
::经过26年发展,传统浏览器形成了固定风格,有些操作很繁琐,比如:谷歌浏览器的导入书签是三级菜单(图1)、进入书签导入窗口,有五项:浏览记录、收藏夹/书签、已保存的密码、搜索引擎和自动填充表单数据(图2),除了收藏夹/书签外,其他多余。浏览器进化到简约全屏模式是必然选择,迫切需要浏览器导入书签菜单减少层次,以提高效率,改善用户体验。技术实现要素:
发明内容:浏览网页的任意空白处右击弹出菜单,增加“书签管理”,二级菜单(图3)有:导出书签和导入书签,比谷歌浏览器少一级菜单,且采用鼠标右击任意空白处非常方便,大大改善用户体验。“导入书签”窗口(图4)有默认导入源文件,就是导出书签默认文件;如点击右边的文件夹图标,则打开文件夹搜寻(图5)原来保存的来自谷歌、360、火狐狸、ie或edge浏览器的任何html超文本书签文件(图6),可选择“覆盖或添加书签”(图7),系统采用同一段代码导入常用浏览器书签的图标、url地址、网页短标题和长标题,举例中导入谷歌书签后,我的书签有三列(图8)。导入ie书签时忽略图标,因ie的书签文件不包含图标信息,需实时下载,影响用户体验,留到上网时更新图标。“导出书签”会显示“导出我的书签~备份保存”窗口(图9),默认保存在“下载”文件夹。发明人开发成功的hahayaya极速简约全屏浏览器中,实现了上述“书签管理~导入与导出”功能,程序非常精练,仅227行python代码,绿色环保。附图说明图1.谷歌浏览器“导入书签和设置”三级菜单示意图图2.谷歌浏览器“导入书签和设置”窗口的五个选项示意图图3.hahayaya极速简约防盗linux全屏浏览器网页空白处右击菜单“书签管理”功能图4.hahayaya极速简约防盗linux全屏浏览器的导入书签~导入书签源窗口图5.hahayaya极速简约防盗linux全屏浏览器的导入书签源~请选择想导入的书签源文件图6.hahayaya极速简约防盗linux全屏浏览器的导入书签~导入书签源~选中书签源界面图7.hahayaya极速简约防盗linux全屏浏览器的导入书签~你想覆盖现有书签吗~界面图8.hahayaya极速简约防盗linux全屏浏览器的导入书签~我的书签~三列书签界面图9.hahayaya极速简约防盗linux全屏浏览器的导出书签~导出我的书签~备份保存~界面。具体实施方式采用linuxcentos7.7系统的python3.7版语言、pyqt5和pyqtwebeingine开发包实现“极速简约防盗linux全屏浏览器”,开发平台是pycharmcommunity2019.3版。开发成功的hahayaya极速简约防盗全屏浏览器中,实现了
发明内容所述的“书签管理~导入与导出”功能,程序非常精练,仅227行python代码,绿色环保。注释行以#开头,/是折行连接符,简单易懂的代码不加注释,实现“书签管理~导入与导出”软件功能的重要代码用粗体显示,代码如下: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=[]#储存网页父实例数组变量……省略无关代码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_item(self,url,title,icon):#创建书签数据项方法result=qstandarditem(title)result.setflags(qt.itemisenabled|qt.itemisselectable)result.setdata(url,_url_role)ificonisnotnone:result.seticon(icon)returnresult……省略无关代码def_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)returnresult……省略无关代码defwrite_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)……省略无关代码defexport_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>'+'<!--this/isanautomaticallygeneratedfile.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()#把本网页父实例设置为捕获键盘,以便进入全屏模式……省略无关代码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))……省略无关代码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()#主窗口最大化显示……省略无关代码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_1……省略无关代码if__name__=="__main__":#主程序argvs=sys.argvargvs.append("--no-sandbox")qcoreapplication.setattribute(qt.aa_usesoftwareopengl)app=qapplication(argvs)window=mybrowser()#实例化主窗口和加载首页面window.show()#显示主窗口sys.exit(app.exec_())以上全屏浏览器有关书签管理的代码共227行,注释行除外。当前第1页12当前第1页12
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1