1

I am making a very simple browser with a search box using PyQt5 WebKit. This is the code I'm using:

import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QMainWindow, QGridLayout)
from PyQt5.QtWebKitWidgets import QWebView


class App(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        centralWidget   = QWidget()
        self.setCentralWidget(centralWidget)

        self.searchbox = QLineEdit("", self)
        self.go = QPushButton('Go', self)
        self.go.clicked.connect(self.gourl)  
        self.webview = Browser()        

        self.grid = QGridLayout(centralWidget)
        self.grid.addWidget(self.webview, 0, 0, 1, 4)
        self.grid.addWidget(self.searchbox, 1, 0)
        self.grid.addWidget(self.go, 1, 1)

    def gourl(self):
        url = self.searchbox.text()
        self.webview.load(QUrl(url))


class Browser(QWebView):   #(QWebView):
    windowList = []
    def createWindow(self, QWebEnginePage_WebWindowType):
        App.setCentralWidget(Browser())
        #new_window.show()
        self.windowList.append(App())  
        return Browser()

if __name__ == "__main__":    
    app = QApplication(sys.argv)
    box = App()
    box.setWindowTitle('Browser')
    box.resize(600, 500)
    box.show()
    sys.exit(app.exec_())

I want to keep the URL in the box updated with whatever current URL the user is on. I have no idea how to go about this, any help would be appreciated.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
Sid
  • 2,174
  • 1
  • 13
  • 29

1 Answers1

1

Below is a re-write of your example which should do what you want.

The Browser class has been fixed so that it creates a new instance of App when a new window is requested. You can test this by right-clicking on a link and selecting Open in New Window. The search box will automatically update with the new url whenever it changes.

import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import (QApplication, QWidget, QPushButton, QAction, QLineEdit, QMessageBox, QMainWindow, QGridLayout)
from PyQt5.QtWebKitWidgets import QWebView


class App(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        centralWidget   = QWidget()
        self.setCentralWidget(centralWidget)

        self.searchbox = QLineEdit("", self)
        self.go = QPushButton('Go', self)
        self.go.clicked.connect(self.gourl)
        self.webview = Browser()
        self.webview.urlChanged.connect(self.handleUrlChanged)

        self.grid = QGridLayout(centralWidget)
        self.grid.addWidget(self.webview, 0, 0, 1, 4)
        self.grid.addWidget(self.searchbox, 1, 0)
        self.grid.addWidget(self.go, 1, 1)

    def gourl(self):
        url = self.searchbox.text()
        self.webview.load(QUrl(url))

    def handleUrlChanged(self, url):
        self.searchbox.setText(url.toString())


class Browser(QWebView):
    windowList = []

    def createWindow(self, wintype):
        window = App()
        self.windowList.append(window)
        window.show()
        return window.webview

    def closeEvent(self, event):
        self.windowList.remove(self)
        super().closeEvent(event)


if __name__ == "__main__":

    app = QApplication(sys.argv)
    box = App()
    box.setWindowTitle('Browser')
    box.resize(600, 500)
    box.show()
    sys.exit(app.exec_())
ekhumoro
  • 115,249
  • 20
  • 229
  • 336
  • you must to check if QLineEdit text is a valid Url or will crash right? – Linux Oct 22 '21 at 10:35
  • @Linux No, it won't crash. It just won't load the url - and then either show an error page, or *about:blank*. But what exactly do you mean by "valid"? If you mean *syntactically valid*, then I suppose you could use `url = QUrl.fromUserInput(text)` and check `url.isValid()`. However, if you mean *semantically valid*, then it's impossible to know - a http request could return a 404 or 503 (or whatever) at any time. It's really a waste of time trying to work out in advance what *might happen* - just let the browser deal with it – ekhumoro Oct 22 '21 at 12:50