Learn How to Create a Simple Web Browser
In this tutorial, we will create a simple web browser using PySide2, a Python binding for the Qt framework. The web browser will have basic functionality such as navigating to websites, a custom title bar, and the ability to minimize, maximize, and close the window.
If you are new to Python programming, feel free to check out our python tutorials to get you started.
Prerequisites
Before we start, ensure you have the following:
- Python installed on your system.
- PySide2 library installed. You can install it using pip:
pip install PySide2Getting Started
Let’s break down the key components of this code:
- We import the necessary modules from PySide2.
- We create a custom title bar using the
TaskBarclass, which inherits fromQFrame. The title bar includes a search bar, search button, minimize button, maximize button, and close button. - The
searchmethod is responsible for loading the entered URL in theQWebEngineView. It checks if the URL starts with “http://” and adds it if not. - The
updateUrlmethod updates the text in the search bar with the current URL of theQWebEngineView. - The
mousePressEventandmouseMoveEventmethods handle window dragging when the user clicks and drags the title bar. - In the
Browserclass, we set up the main window and create the web browser’s interface. This includes aQWebEngineViewfor displaying web content and aTaskBarfor the custom title bar. - The
addStylemethod sets the stylesheet for styling the window, title bar, and other UI elements. - Finally, we define functions for window actions like minimizing, maximizing, and closing the window.
Let’s start by creating a basic structure for our web browser. Save the following code in a Python file (e.g., web_browser.py):
from PySide2.QtGui import *
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtWebEngineWidgets import QWebEngineView
import sys
# Define the TaskBar class for the custom title bar
class TaskBar(QFrame):
searchbar = None
drag_start_pos = None
window = None
def __init__(self, window):
super(TaskBar, self).__init__()
self.window = window
self.display()
def updateUrl(self):
self.searchbar.setText(self.window.view.url().toString())
def search(self):
url = self.searchbar.text()
if not url.startswith('http://'):
url = 'http://' + url
self.window.view.setUrl(QUrl(url))
def display(self):
layout = QHBoxLayout()
layout.setMargin(0)
layout.setAlignment(Qt.AlignTop)
inputBox = QLineEdit("http://www.google.com")
self.searchbar = inputBox
layout.addWidget(inputBox)
searchButton = QPushButton("\U0001F50D")
searchButton.clicked.connect(self.search)
layout.addWidget(searchButton)
minimizeButton = QPushButton("−")
minimizeButton.clicked.connect(minimizeWindow)
layout.addWidget(minimizeButton)
maximizeButton = QPushButton("\u25A1")
maximizeButton.clicked.connect(maximizeWindow)
layout.addWidget(maximizeButton)
cancelButton = QPushButton("\u2716")
cancelButton.clicked.connect(cancelWindow)
layout.addWidget(cancelButton)
self.setLayout(layout)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drag_start_pos = event.globalPos() - window.pos()
event.accept()
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton:
if self.drag_start_pos:
new_pos = event.globalPos() - self.drag_start_pos
window.move(new_pos)
event.accept()
class Browser(QMainWindow):
view = None
def __init__(self):
super(Browser, self).__init__()
self.setMinimumSize(QSize(800, 600))
self.setWindowTitle("Browser")
self.setWindowFlag(Qt.WindowTitleHint, False)
self.setWindowFlag(Qt.FramelessWindowHint, True)
self.display()
self.show()
def display(self):
mainWidget = QWidget()
self.setCentralWidget(mainWidget)
layout = QVBoxLayout()
layout.setMargin(0)
mainWidget.setLayout(layout)
taskbar = TaskBar(self)
layout.addWidget(taskbar)
webView = QWebEngineView()
webView.sizePolicy().setVerticalPolicy(QSizePolicy.Expanding)
webView.loadFinished.connect(taskbar.updateUrl)
webView.urlChanged.connect(taskbar.updateUrl)
layout.addWidget(webView)
self.view = webView
taskbar.search()
self.addStyle()
def addStyle(self):
style = '''
QMainWindow{
background:#fff;
border:1px solid #ccc;
}
QFrame{
padding:15px;
background:#ccc;
max-height:35px;
}
QLineEdit{
border-radius:12px;
height:25px;
border:1px solid #bbb;
}
QWebEngineView{
height:100%;
}
QPushButton{
max-width:25px;
}
'''
self.setStyleSheet(style)
# Define functions for window actions
def cancelWindow():
App.quit()
def maximizeWindow():
if window.isMaximized():
window.showNormal()
else:
window.showMaximized()
def minimizeWindow():
window.showMinimized()
if __name__ == "__main__":
App = QApplication()
window = Browser()
sys.exit(App.exec_())Explanation
Let’s break down the code block by block and explain the purpose of each part:
from PySide2.QtGui import *
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtWebEngineWidgets import QWebEngineView
import sys- In this section, we import the necessary modules and classes from PySide2. Here’s what each import statement does:
from PySide2.QtGui import *: Imports various GUI-related classes and functions.from PySide2.QtCore import *: Imports core functionality, including Qt enums and types.from PySide2.QtWidgets import *: Imports widgets and layout managers.from PySide2.QtWebEngineWidgets import QWebEngineView: Imports theQWebEngineViewclass, which allows us to display web content in our application.import sys: Imports thesysmodule for handling system-related functionality.
# Define the TaskBar class for the custom title bar
class TaskBar(QFrame):
searchbar = None
drag_start_pos = None
window = None
- Here, we define the
TaskBarclass, which is responsible for creating the custom title bar. The class has three class-level attributes:searchbar,drag_start_pos, andwindow.
def __init__(self, window):
super(TaskBar, self).__init__()
self.window = window
self.display()
- The
__init__method is the constructor of theTaskBarclass. It initializes the title bar and sets thewindowattribute, which refers to the main application window.
def updateUrl(self):
self.searchbar.setText(self.window.view.url().toString())
- The
updateUrlmethod updates the text in the search bar (the URL input field) with the current URL of the web view in the main application window.
def search(self):
url = self.searchbar.text()
if not url.startswith('http://'):
url = 'http://' + url
self.window.view.setUrl(QUrl(url))
- The
searchmethod is called when the user clicks the search button. It retrieves the text from the search bar, checks if it starts with “http://” (to ensure it’s a valid URL), and then loads the URL in the web view.
def display(self):
layout = QHBoxLayout()
layout.setMargin(0)
layout.setAlignment(Qt.AlignTop)
- The
displaymethod sets up the layout of the custom title bar. It creates a horizontal layout (QHBoxLayout) and adjusts its properties, such as margins and alignment.
inputBox = QLineEdit("http://www.google.com")
self.searchbar = inputBox
layout.addWidget(inputBox)
- The method creates a QLineEdit widget as the search bar and sets its initial text to “http://www.google.com“. It also assigns the search bar to the
searchbarattribute for future reference.
searchButton = QPushButton("\U0001F50D")
searchButton.clicked.connect(self.search)
layout.addWidget(searchButton)
- This section creates a QPushButton with a search icon. It connects the button’s click event to the
searchmethod so that clicking the button triggers the search functionality.
minimizeButton = QPushButton("−")
minimizeButton.clicked.connect(minimizeWindow)
layout.addWidget(minimizeButton)
- The code creates a minimize button and connects its click event to the
minimizeWindowfunction, allowing the user to minimize the application window.
maximizeButton = QPushButton("\u25A1")
maximizeButton.clicked.connect(maximizeWindow)
layout.addWidget(maximizeButton)
- Here, a maximize button with a symbol is created. Its click event is connected to the
maximizeWindowfunction to handle maximizing and restoring the window.
cancelButton = QPushButton("\u2716")
cancelButton.clicked.connect(cancelWindow)
layout.addWidget(cancelButton)
- This part creates a close button with a “✖” symbol. Its click event is connected to the
cancelWindowfunction for closing the application.
self.setLayout(layout)
- Finally, the
setLayoutmethod sets the layout of theTaskBar, ensuring that all the widgets are arranged correctly.
Generally,this part of the code defines the TaskBar class and its methods for creating the custom title bar of the web browser application. The title bar includes a URL input field, a search button, a minimize button, a maximize button, and a close button.
Now, let’s continue with the Browser class:
class Browser(QMainWindow):
view = None
- In this section, we define the
Browserclass, which represents the main application window. It has a class-level attribute calledviewto hold theQWebEngineViewwidget.
def __init__(self):
super(Browser, self).__init__()
self.setMinimumSize(QSize(800, 600))
self.setWindowTitle("Browser")
self.setWindowFlag(Qt.WindowTitleHint, False)
self.setWindowFlag(Qt.FramelessWindowHint, True)
self.display()
self.show()
- The
__init__method is the constructor of theBrowserclass. It initializes the main application window by setting its minimum size, title, and flags to make it frameless.
def display(self):
mainWidget = QWidget()
self.setCentralWidget(mainWidget)
- The
displaymethod sets up the user interface of the main application window. It creates a main widget that acts as the central widget for theQMainWindow.
layout = QVBoxLayout()
layout.setMargin(0)
mainWidget.setLayout(layout)
- This part initializes a vertical layout (
QVBoxLayout) for the main widget, removes margins to maximize space utilization, and sets the layout for the main widget.
taskbar = TaskBar(self)
layout.addWidget(taskbar)
- The code creates an instance of the
TaskBarclass (the custom title bar) and adds it to the vertical layout of the main window.
webView = QWebEngineView()
webView.sizePolicy().setVerticalPolicy(QSizePolicy.Expanding)
webView.loadFinished.connect(taskbar.updateUrl)
webView.urlChanged.connect(taskbar.updateUrl)
layout.addWidget(webView)
self.view = webView
- This section creates a
QWebEngineViewwidget for displaying web content. It sets its vertical size policy to expanding so that it takes up available vertical space. - Event connections are established between the web view’s
loadFinishedandurlChangedsignals and theupdateUrlmethod of theTaskBarclass to keep the URL bar updated.
taskbar.search()
- The
searchmethod of theTaskBarclass is called to initialize the web view with a default URL (http://www.google.com in this case).
self.addStyle()
- The
addStylemethod is called to apply stylesheet styles to the main window, title bar, and UI elements.
def addStyle(self):
style = '''
QMainWindow{
background:#fff;
border:1px solid #ccc;
}
QFrame{
padding:15px;
background:#ccc;
max-height:35px;
}
QLineEdit{
border-radius:12px;
height:25px;
border:1px solid #bbb;
}
QWebEngineView{
height:100%;
}
QPushButton{
max-width:25px;
}
'''
self.setStyleSheet(style)
- The
addStylemethod defines a stylesheet with CSS-like rules to style the appearance of various elements in the application, including the main window, title bar, input fields, and buttons. For a better understanding of the CSS look at our CSS tutorials.
# Define functions for window actions
def cancelWindow():
App.quit()
def maximizeWindow():
if window.isMaximized():
window.showNormal()
else:
window.showMaximized()
def minimizeWindow():
window.showMinimized()
- Here, we define three functions for window actions:
cancelWindow: Closes the application.maximizeWindow: Toggles between maximizing and restoring the application window.minimizeWindow: Minimizes the application window.
if __name__ == "__main__":
App = QApplication()
window = Browser()
sys.exit(App.exec_())
- The
if __name__ == "__main__":block is the entry point of the application. - It initializes the
QApplication, creates an instance of theBrowserclass (the main window), and starts the application event loop usingApp.exec_(). - The
sys.exitcall ensures that the application exits gracefully when the user closes the window.
This code defines the Browser class, sets up the main application window, creates the custom title bar using the TaskBar class, and connects various UI elements to their respective functionality. It also handles styling and window actions such as minimize, maximize, and close.
Running the Web Browser
To run the web browser, save the code in a file (e.g., web_browser.py) and execute it with Python:
python web_browser.pyYou will see a simple web browser window.
