The widget QWebView can be used to render webpages. QWebView uses the QtWebkit web browsing module. To show a website simply call the load(url) method.

QWebview suports navigational functions: forward(), back(), reload(), stop().

Note: QWebView only shows the webpage contents. Code for a python webbrowser below.

Related course:
Create PyQt Desktop Appications with Python (GUI)

python webbrowser

In the example below we have a complete webbrowser. It supports tabs, basic navigation and a keyboard shortcut. It’s a minimal example that is extensible.

QtWebKit

The look and feel depends on your operating system, you can make it look like Mac or Windows if you want. Thsi is is all with Python PyQt.

# https://pythonprogramminglanguage.com/webkit-browser/
#!/usr/bin/python

from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebKitWidgets import *
from PyQt5.QtGui import *
import sip
import sys

class tabdemo(QMainWindow):
def __init__(self):
super(tabdemo, self).__init__()
self.setAttribute(Qt.WA_DeleteOnClose)
self.tabs = QTabWidget()
self.tabs.setTabsClosable(True)
self.tabs.tabCloseRequested.connect(self.closeTab)
self.tab1 = QWidget()
self.tabWebView = []
self.lNameLine = []
self.tabs.addTab(self.tab1,"New Tab")
self.tab1UI(self.tab1)
self.setWindowTitle("PyQt https://pythonprogramminglanguage.com")
self.setCentralWidget(self.tabs)
self.showMaximized()
QShortcut(QKeySequence("Ctrl+T"), self, self.addTab)

def addTab(self):
tab = QWidget()
self.tabs.addTab(tab,"New Tab")
self.tab1UI(tab)

index = self.tabs.currentIndex()
self.tabs.setCurrentIndex( index + 1 )
#self.tabWebView[self.tabs.currentIndex()].load( QUrl('about:blank'))

def goBack(self):
index = self.tabs.currentIndex()
self.tabWebView[index].back()

def goNext(self):
index = self.tabs.currentIndex()
self.tabWebView[index].forward()

def goRefresh(self):
index = self.tabs.currentIndex()
self.tabWebView[index].reload()

def changePage(self):
index = self.tabs.currentIndex()
pageTitle = self.sender().title()[:15]
self.tabs.setTabText(index, pageTitle);
self.lNameLine[self.tabs.currentIndex()].setText(self.sender().url().url())

def load_started(self):
return

def tab1UI(self,tabName):
webView = QWebView()

backButton = QPushButton("")
backIcon = QIcon()
backIcon.addPixmap(QPixmap("back.svg"))
backButton.setIcon(backIcon)
backButton.setFlat(True)

nextButton = QPushButton("")
nextIcon = QIcon()
nextIcon.addPixmap(QPixmap("next.svg"))
nextButton.setIcon(nextIcon)
nextButton.setFlat(True)

refreshButton = QPushButton("")
refreshIcon = QIcon()
refreshIcon.addPixmap(QPixmap("refresh.svg"))
refreshButton.setIcon(refreshIcon)
refreshButton.setFlat(True)

backButton.clicked.connect(self.goBack)
nextButton.clicked.connect(self.goNext)
refreshButton.clicked.connect(self.goRefresh)

self.newTabButton = QPushButton("+")
self.destroyTabButton = QPushButton("-")
self.tabWidget = QTabWidget()

nameLine = QLineEdit()
nameLine.returnPressed.connect(self.requestUri)

tabGrid = QGridLayout()

tabGrid.setContentsMargins(0,0,0,0)

navigationFrame = QWidget()
navigationFrame.setMaximumHeight(32)

navigationGrid = QGridLayout(navigationFrame)
navigationGrid.setSpacing(0)
navigationGrid.setContentsMargins(0,0,0,0)
navigationGrid.addWidget(backButton,0,1)
navigationGrid.addWidget(nextButton,0,2)
navigationGrid.addWidget(refreshButton,0,3)
navigationGrid.addWidget(nameLine,0,4)

tabGrid.addWidget(navigationFrame)

webView = QWebView()
htmlhead = "<head><style>body{ background-color: #fff; }</style></head><body></body>";
webView.setHtml(htmlhead)

#webView.loadProgress.connect(self.loading)
webView.loadFinished.connect(self.changePage)

frame = QFrame()
frame.setFrameStyle(QFrame.Panel)

gridLayout = QGridLayout(frame);
#gridLayout.setObjectName(QStringLiteral("gridLayout"));
gridLayout.setContentsMargins(0, 0, 0, 0);
gridLayout.addWidget(webView, 0, 0, 1, 1);
frame.setLayout(gridLayout)

self.tabWebView.append(webView)
self.tabWidget.setCurrentWidget(webView)
self.lNameLine.append(nameLine)
tabGrid.addWidget(frame)
tabName.setLayout(tabGrid)

def tab2UI(self):
vbox = QVBoxLayout()
tbl1 = QTableWidget()
tbl1.setRowCount(5)
tbl1.setColumnCount(5)
vbox.addWidget(tbl1)
tbl1.setItem(0, 0, QTableWidgetItem("1")) # row, col
self.tab2.setLayout(vbox)

def requestUri(self):
if self.tabs.currentIndex() != -1:

urlText = self.lNameLine[self.tabs.currentIndex()].text()

##########################
# no protocol?
if 'http' not in urlText:
self.lNameLine[self.tabs.currentIndex()].setText( 'https://' + urlText)

url = QUrl(self.lNameLine[self.tabs.currentIndex()].text())

print(self.tabs.currentIndex())
if url.isValid():
self.tabWebView[self.tabs.currentIndex()].load(url)
else:
print("Url not valid")
else:
print("No tabs open, open one first.")

def closeTab(self,tabId):
print(tabId)
del self.lNameLine[tabId]
del self.tabWebView[tabId]
self.tabs.removeTab(tabId)

def main():
app = QApplication(sys.argv)
ex = tabdemo()
ex.show()
sys.exit(app.exec_())

if __name__ == '__main__':
main()

If you are new to Python PyQt, then I highly recommend this book.

Download PyQt Examples