使用QtWebKit 做一个简单的浏览器.
mybrowserUI.ui
1 <?xml version="1.0" encoding="UTF-8"?> 2 <ui version="4.0"> 3 <class>MainWindow</class> 4 <widget class="QMainWindow" name="MainWindow"> 5 <property name="geometry"> 6 <rect> 7 <x>0</x> 8 <y>0</y> 9 <width>522</width> 10 <height>336</height> 11 </rect> 12 </property> 13 <property name="windowTitle"> 14 <string>MainWindow</string> 15 </property> 16 <widget class="QWidget" name="centralwidget"> 17 <layout class="QVBoxLayout" name="verticalLayout"> 18 <item> 19 <widget class="QWebView" name="webView"> 20 <property name="url"> 21 <url> 22 <string>about:blank</string> 23 </url> 24 </property> 25 </widget> 26 </item> 27 </layout> 28 </widget> 29 <widget class="QMenuBar" name="menubar"> 30 <property name="geometry"> 31 <rect> 32 <x>0</x> 33 <y>0</y> 34 <width>522</width> 35 <height>23</height> 36 </rect> 37 </property> 38 <widget class="QMenu" name="menu_F"> 39 <property name="title"> 40 <string>文件【&F】</string> 41 </property> 42 <widget class="QMenu" name="menu"> 43 <property name="title"> 44 <string>新建</string> 45 </property> 46 <property name="icon"> 47 <iconset resource="qrcc.qrc"> 48 <normaloff>:/img/resource/worm.gif</normaloff>:/img/resource/worm.gif</iconset> 49 </property> 50 <addaction name="actionNew_Windows"/> 51 </widget> 52 <addaction name="menu"/> 53 <addaction name="actionResoures"/> 54 <addaction name="separator"/> 55 <addaction name="actionClose"/> 56 </widget> 57 <widget class="QMenu" name="menuAbout"> 58 <property name="title"> 59 <string>关于【&A】</string> 60 </property> 61 <addaction name="actionAboutUS"/> 62 </widget> 63 <widget class="QMenu" name="menu_2"> 64 <property name="title"> 65 <string>工具【&T】</string> 66 </property> 67 <addaction name="actionLLink"/> 68 <addaction name="separator"/> 69 <addaction name="actionshot"/> 70 </widget> 71 <addaction name="menu_F"/> 72 <addaction name="menu_2"/> 73 <addaction name="menuAbout"/> 74 </widget> 75 <widget class="QToolBar" name="toolBar"> 76 <property name="windowTitle"> 77 <string>toolBar</string> 78 </property> 79 <attribute name="toolBarArea"> 80 <enum>TopToolBarArea</enum> 81 </attribute> 82 <attribute name="toolBarBreak"> 83 <bool>false</bool> 84 </attribute> 85 <addaction name="actionBack"/> 86 <addaction name="actionForward"/> 87 <addaction name="actionRefresh"/> 88 <addaction name="actionPause"/> 89 <addaction name="actionHome"/> 90 <addaction name="separator"/> 91 <addaction name="actionGo"/> 92 </widget> 93 <action name="actionClose"> 94 <property name="icon"> 95 <iconset resource="qrcc.qrc"> 96 <normaloff>:/img/resource/birthday.gif</normaloff>:/img/resource/birthday.gif</iconset> 97 </property> 98 <property name="text"> 99 <string>关闭</string> 100 </property> 101 </action> 102 <action name="actionBack"> 103 <property name="icon"> 104 <iconset resource="qrcc.qrc"> 105 <normaloff>:/img/resource/back.png</normaloff>:/img/resource/back.png</iconset> 106 </property> 107 <property name="text"> 108 <string>back</string> 109 </property> 110 <property name="toolTip"> 111 <string>后退</string> 112 </property> 113 </action> 114 <action name="actionForward"> 115 <property name="icon"> 116 <iconset resource="qrcc.qrc"> 117 <normaloff>:/img/resource/forward.png</normaloff>:/img/resource/forward.png</iconset> 118 </property> 119 <property name="text"> 120 <string>forward</string> 121 </property> 122 <property name="toolTip"> 123 <string>前进</string> 124 </property> 125 </action> 126 <action name="actionHome"> 127 <property name="icon"> 128 <iconset resource="qrcc.qrc"> 129 <normaloff>:/img/resource/home.png</normaloff>:/img/resource/home.png</iconset> 130 </property> 131 <property name="text"> 132 <string>home</string> 133 </property> 134 <property name="toolTip"> 135 <string>主页</string> 136 </property> 137 </action> 138 <action name="actionPause"> 139 <property name="icon"> 140 <iconset resource="qrcc.qrc"> 141 <normaloff>:/img/resource/pause.png</normaloff>:/img/resource/pause.png</iconset> 142 </property> 143 <property name="text"> 144 <string>pause</string> 145 </property> 146 <property name="toolTip"> 147 <string>暂停</string> 148 </property> 149 </action> 150 <action name="actionRefresh"> 151 <property name="icon"> 152 <iconset resource="qrcc.qrc"> 153 <normaloff>:/img/resource/refresh.png</normaloff>:/img/resource/refresh.png</iconset> 154 </property> 155 <property name="text"> 156 <string>refresh</string> 157 </property> 158 <property name="toolTip"> 159 <string>刷新</string> 160 </property> 161 </action> 162 <action name="actionGo"> 163 <property name="icon"> 164 <iconset resource="qrcc.qrc"> 165 <normaloff>:/img/resource/enter.jpg</normaloff>:/img/resource/enter.jpg</iconset> 166 </property> 167 <property name="text"> 168 <string>go</string> 169 </property> 170 <property name="toolTip"> 171 <string>确定前往</string> 172 </property> 173 </action> 174 <action name="actionNew_Windows"> 175 <property name="icon"> 176 <iconset resource="qrcc.qrc"> 177 <normaloff>:/img/resource/newwindows.gif</normaloff>:/img/resource/newwindows.gif</iconset> 178 </property> 179 <property name="text"> 180 <string>New Windows</string> 181 </property> 182 </action> 183 <action name="actionResoures"> 184 <property name="icon"> 185 <iconset resource="qrcc.qrc"> 186 <normaloff>:/img/resource/cool.gif</normaloff>:/img/resource/cool.gif</iconset> 187 </property> 188 <property name="text"> 189 <string>查看源码</string> 190 </property> 191 </action> 192 <action name="actionLLink"> 193 <property name="icon"> 194 <iconset resource="qrcc.qrc"> 195 <normaloff>:/img/resource/cry.gif</normaloff>:/img/resource/cry.gif</iconset> 196 </property> 197 <property name="text"> 198 <string>高亮链接</string> 199 </property> 200 </action> 201 <action name="actionAboutUS"> 202 <property name="icon"> 203 <iconset resource="qrcc.qrc"> 204 <normaloff>:/img/resource/eat.gif</normaloff>:/img/resource/eat.gif</iconset> 205 </property> 206 <property name="text"> 207 <string>关于我们</string> 208 </property> 209 </action> 210 <action name="actionshot"> 211 <property name="icon"> 212 <iconset resource="qrcc.qrc"> 213 <normaloff>:/img/resource/sex.gif</normaloff>:/img/resource/sex.gif</iconset> 214 </property> 215 <property name="text"> 216 <string>截图网页</string> 217 </property> 218 </action> 219 </widget> 220 <customwidgets> 221 <customwidget> 222 <class>QWebView</class> 223 <extends>QWidget</extends> 224 <header>QtWebKit/QWebView</header> 225 </customwidget> 226 </customwidgets> 227 <resources> 228 <include location="qrcc.qrc"/> 229 </resources> 230 <connections/> 231 </ui>
mainbrowser.py
1 # -*- coding: UTF8 -*- 2 3 from PyQt4 import QtGui, QtCore, QtWebKit, QtNetwork 4 from PyQt4.QtCore import QUrl 5 from mybrowserUI import Ui_MainWindow 6 import sys, os 7 import qrcc 8 9 reload(sys) 10 sys.setdefaultencoding("utf-8") 11 12 class MainMyBrowser(QtGui.QMainWindow): 13 def __init__(self,parent=None): 14 super(MainMyBrowser,self).__init__(parent) 15 self.Ui = Ui_MainWindow() 16 self.Ui.setupUi(self) 17 self.setWindowTitle('MyBrowser V2.1') 18 self.statusBar().showMessage('Ready') 19 self.initLayout() 20 self.initSimpleEvent() 21 url = QUrl('http://m.hao123.com') 22 self.Ui.webView.load(url) 23 24 25 # 初始化Layout 26 def initLayout(self): 27 self.Ui.actionClose.setStatusTip(u'退出') 28 ''' 29 添加地址栏,输入框 lineEdit 30 ''' 31 self.lblAddress = QtGui.QLabel(u"地址:", self.Ui.toolBar) 32 self.Ui.toolBar.insertWidget(self.Ui.actionGo, self.lblAddress) #(self, QAction before #控件之前, QWidget widget # 改控件) 33 self.addressEdit = QtGui.QLineEdit(self.Ui.toolBar) 34 self.addressEdit.setFixedHeight(30) # lineEdit 框高度 35 self.addressEdit.setFont(QtGui.QFont('.SansSerif', 19)) # 设置框内字体 36 self.addressEdit.setStatusTip(u'请输入链接地址') 37 self.Ui.actionGo.setStatusTip(u'前往链接') 38 self.Ui.toolBar.insertWidget(self.Ui.actionGo, self.addressEdit) 39 40 41 # 初始化效果事件 42 def initSimpleEvent(self): 43 self.progress = 0 44 self.Ui.actionClose.triggered.connect(QtGui.qApp.quit) # 退出 45 self.addressEdit.returnPressed.connect(self.changeLocation) #地址框回车触发GO效果 46 self.Ui.webView.loadFinished.connect(self.adjustLocation) # 加载完成改变输入框text() 47 self.Ui.webView.titleChanged.connect(self.adjustTitle) #标题修改触发 48 self.Ui.webView.loadProgress.connect(self.setProgress) # 显示加载进度 49 self.Ui.actionGo.triggered.connect(self.changeLocation) 50 self.Ui.actionBack.triggered.connect(self.Ui.webView.back) #返回 51 self.Ui.actionPause.triggered.connect(self.Ui.webView.stop) 52 self.Ui.actionRefresh.triggered.connect(self.Ui.webView.reload) 53 self.Ui.actionForward.triggered.connect(self.Ui.webView.forward) 54 self.Ui.actionHome.triggered.connect(self.GoHome) # 无法获取主页**=> self.Ui.webView.gohome 55 self.Ui.actionResoures.triggered.connect(self.viewSource) # 查看源码 56 self.Ui.actionNew_Windows.triggered.connect(self.newindows) # 新打开一个windows_tab 57 self.Ui.actionLLink.triggered.connect(self.highlightAllLinks) # 高亮 58 self.Ui.actionAboutUS.triggered.connect(self.aboutus) # 关于我们 59 self.Ui.actionshot.triggered.connect(self.shot) # 截图 60 ''' 61 Webkit屏蔽右键菜单 62 ''' 63 self.Ui.webView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) 64 self.Ui.webView.customContextMenuRequested.connect(self.showContextMenu) 65 self.Ui.webView.contextMenu = QtGui.QMenu(self) 66 67 68 69 70 #输入框改变时 71 def changeLocation(self): 72 url = QtCore.QUrl.fromUserInput(self.addressEdit.text()) 73 self.Ui.webView.load(url) 74 self.Ui.webView.setFocus() 75 # 调整输入框的显示 76 def adjustLocation(self): 77 self.addressEdit.setText(self.Ui.webView.url().toString()) 78 #调整windows标题显示 79 def adjustTitle(self): 80 if 0 < self.progress < 100: 81 self.setWindowTitle("%s (%s%%)" % (self.Ui.webView.title(), self.progress)) 82 else: 83 self.setWindowTitle(self.Ui.webView.title()) 84 #显示加载进度 85 def setProgress(self, p): 86 self.progress = p 87 self.adjustTitle() 88 89 #模拟首页 90 def GoHome(self): 91 self.Ui.webView.load(QUrl('http://www.baidu.com')) 92 #查看源码 93 def viewSource(self): 94 accessManager = self.Ui.webView.page().networkAccessManager() 95 request = QtNetwork.QNetworkRequest(self.Ui.webView.url()) 96 reply = accessManager.get(request) 97 reply.finished.connect(self.slotSourceDownloaded) 98 #查看源码 99 def slotSourceDownloaded(self): 100 reply = self.sender() 101 self.textEdit = QtGui.QTextEdit(None) 102 self.textEdit.setAttribute(QtCore.Qt.WA_DeleteOnClose) 103 self.textEdit.show() 104 self.textEdit.setPlainText(QtCore.QTextStream(reply).readAll()) 105 self.textEdit.resize(600, 400) 106 reply.deleteLater() 107 108 #新打开tab 109 # @QtCore.pyqtSlot() 110 def newindows(self): 111 window = MainMyBrowser(self) 112 window.show() 113 if self.addressEdit.text().isEmpty(): 114 return; 115 116 # 高亮 117 def highlightAllLinks(self): 118 code = """$('a').each( 119 function () { 120 $(this).css('background-color', 'yellow') 121 } 122 )""" 123 self.Ui.webView.page().mainFrame().evaluateJavaScript(code) 124 125 # 关于我们 126 def aboutus(self): 127 QtGui.QMessageBox.about(self, "About WebBrowser",u"Pyqt 浏览器V2.1, power by dcb3688") 128 129 #截图 130 def shot(self): 131 webView = self.Ui.webView 132 url = QtCore.QUrl.fromUserInput(self.addressEdit.text()) 133 webView.load(QtCore.QUrl(url)) 134 self.webPage = webView.page() 135 self.connect(webView, QtCore.SIGNAL("loadFinished(bool)"), self.savePage) 136 # 截图保存图片 137 def savePage(self,finished): 138 if finished: 139 self.statusBar().showMessage(u'开始截图') 140 size = self.webPage.mainFrame().contentsSize() 141 self.statusBar().showMessage(u"页面宽:%d,页面高:%d" % (size.width(), size.height())) 142 self.webPage.setViewportSize(QtCore.QSize(size.width()+16, size.height())) 143 img = QtGui.QImage(size, QtGui.QImage.Format_ARGB32) 144 painter = QtGui.QPainter(img) 145 self.webPage.mainFrame().render(painter) 146 painter.end() 147 fileName= "shot.png" 148 if img.save(fileName): 149 filePath = os.path.join(os.path.dirname(__file__), fileName) 150 QtGui.QMessageBox.information(self, "About WebBrowser", u'图片保存完成, '+'路径:'+filePath); 151 else: 152 self.statusBar().showMessage(u'截图失败') 153 else: 154 self.statusBar().showMessage(u'网页加载失败') 155 156 # 显示右键内容 157 def showContextMenu(self, pos): 158 self.Ui.webView.contextMenu.move(self.pos() + pos) 159 self.Ui.webView.contextMenu.show() 160 161 def keyPressEvent(self, event): 162 if event.key() ==QtCore.Qt.Key_Escape: 163 self.close() 164 if event.key() == QtCore.Qt.Key_F5: 165 self.changeLocation() 166 167 168 class aboutDialog(QtGui.QWidget): 169 def __init__(self, parent=None): 170 super(aboutDialog, self).__init__(parent) 171 self.show() 172 173 174 175 176 if __name__ == '__main__': 177 app = QtGui.QApplication(sys.argv) 178 appshow = MainMyBrowser() 179 appshow.show() 180 sys.exit(app.exec_())
效果:
网上一个截图: 给工具栏添加action: