PyQt5 QWebEngineView not Displaying Anything - python

So I'm building a simple Web Browser using PyQt5, with QtWebEngineView, it works fine, but when I type something in the address bar and hit enter, the current page changes but the entered web address does not load, the screen remains blank.
It doesn't work with https:// either
"""A Simple Web Browser Written in Python and PyQt5"""
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QAction, QLineEdit
class PyChromeWindow(QMainWindow):
DEFAULT_SEARCH_ENGINE = QUrl("https://www.google.com")
def __init__(self):
super(PyChromeWindow, self).__init__()
self.browser = QWebEngineView(self)
self.browser.setUrl(self.DEFAULT_SEARCH_ENGINE)
# ToolBar
self.browser_tool_bar = QToolBar()
self.addToolBar(self.browser_tool_bar)
# Back Action
self.back_btn = QAction(QIcon('./resources/back_arrow16px.png'), 'Back')
self.back_btn.triggered.connect(self.browser.back)
self.browser_tool_bar.addAction(self.back_btn)
# Forward Action
self.forward_action = QAction(QIcon('./resources/forward_arrow16px.png'), 'Forward')
self.forward_action.triggered.connect(self.browser.forward)
self.browser_tool_bar.addAction(self.forward_action)
# Refresh Action
self.refresh_action = QAction(QIcon('./resources/refresh_icon16px.png'), 'Refresh')
self.refresh_action.triggered.connect(self.browser.reload)
self.browser_tool_bar.addAction(self.refresh_action)
# Home Action
self.home_action = QAction(QIcon('./resources/home_icon16px.png'), 'Home')
self.home_action.triggered.connect(lambda: self.browser.setUrl(self.DEFAULT_SEARCH_ENGINE))
self.browser_tool_bar.addAction(self.home_action)
# Address Bar
self.address_bar = QLineEdit()
self.address_bar.returnPressed.connect(self.navigate_to_url)
self.browser_tool_bar.addWidget(self.address_bar)
self.setCentralWidget(self.browser)
self.showMaximized()
def navigate_to_url(self):
"""Navigate to a specific URL"""
url = QUrl(self.address_bar.text())
self.browser.load(url)
if __name__ == "__main__":
app = QApplication(sys.argv)
app.setApplicationName("PyChrome")
window = PyChromeWindow()
app.exec_()

"www.google.com" is not a valid url for QWebEngineView, in this case you must use QUrl::fromUserInput() which deduces a valid url.
url = QUrl.fromUserInput(self.address_bar.text())

Related

Browse media with PyQT6

I wanted to create a browsing media file with QT so I wrote that :
import sys
import random
import os
import time
from PyQt6 import QtCore, QtWidgets, QtGui
from PyQt6.QtWidgets import QLabel, QPushButton,QSizePolicy, QFileDialog,QHBoxLayout, QVBoxLayout, QSlider, QInputDialog, QMainWindow, QApplication
from PyQt6.QtGui import QPixmap, QShortcut, QKeySequence, QMovie
from PyQt6.QtCore import Qt,QUrl, QTimer, QSettings, QSize, QPoint
from PyQt6.QtMultimediaWidgets import QVideoWidget
from PyQt6.QtMultimedia import QMediaPlayer, QAudioOutput
# Subclass QMainWindow to customize your application's main window
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.posi = 0
#path
if (len( sys.argv ) > 1):
self.folderpath = sys.argv[1]
else:
self.folderpath = "your folder contaianing the files" #<============ DONT FORGET TO FINISH THE PATH WITH /
#pathlist
self.img_list = os.listdir(self.folderpath)
print(self.img_list)
self.setWindowTitle("My App")
self.mediaPlayer = QMediaPlayer(None)
self.videoWidget = QVideoWidget()
self.audio_output = QAudioOutput()
self.mediaPlayer.setVideoOutput(self.videoWidget)
self.mediaPlayer.setAudioOutput(self.audio_output)
self.audio_output.setVolume(50)
self.mediaPlayer.setLoops(-1)
self.mediaPlayer.setSource(QUrl(self.folderpath+self.img_list[0]))
self.mediaPlayer.play()
# Set the central widget of the Window.
self.setCentralWidget(self.videoWidget)
#shortcut
self.shortcut_right = QShortcut(QKeySequence("Right"),self)
self.shortcut_right.activated.connect(self.button_right_clicked)
def button_right_clicked(self, *args):#when navigate right
print("---->")
try:
self.img_list[self.posi+1]
except IndexError:
self.posi = 0
else:
self.posi = self.posi + 1
self.mediaPlayer.setSource(QUrl(self.folderpath+self.img_list[self.posi]))
self.mediaPlayer.play()
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
But sometimes when use the method "button_right_clicked" the program shutdown without any error or closing event. This method is used to navigate through the list of files in the source folder. I'm using only mp4 file for now.
The error comes from this line i presume : self.mediaPlayer.setSource(QUrl(self.folderpath+self.img_list[self.posi]))
Because when i try to set the same media (img_list[0]) file as source, instead of using index self.posi, it doesn't crash.
According to the documentation, it seems to be the approriate way of swapping between media.
Any idea how to solve this problem ?

PyQt5 are taking the screenshot without waiting the api response

I using pyqt5 for taking the screenshot to the URL. it's the react component. it takes the screenshot only component. don't wait till the API response. wanna take a screenshot after get the API response.
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt, QUrl, QTimer
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
class Screenshot(QWebEngineView):
def capture(self, url, output_file):
self.output_file = output_file
self.load(QUrl(url))
self.loadFinished.connect(self.on_loaded)
self.setAttribute(Qt.WA_DontShowOnScreen)
self.show()
def on_loaded(self):
size = self.page().contentsSize().toSize()
self.resize(size)
qt = QTimer()
qt.setInterval(8000)
qt.setSingleShot(True)
qt.singleShot(8000, self.take_screenshot)
def take_screenshot(self):
self.grab().save(self.output_file, b'PNG')
self.app.quit()
app = QApplication([])
s = Screenshot()
s.app = app
s.capture('https://doc.qt.io/qt-5/qtimer.html', 'webpage20.png')
app.exec_()
Note: Under s.capture param URL is just for the example purpose.

view.showMaximised() not working in PyQt5

I am making a web browser using PyQt5. I am using the following code:
import PyQt5
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtWebKitWidgets import QWebView , QWebPage
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtNetwork import *
import sys
from optparse import OptionParser
class Browser(QWebView):
def __init__(self):
# QWebView
self.view = QWebView.__init__(self)
#self.view.setPage(MyBrowser())
self.setWindowTitle('Loading...')
self.titleChanged.connect(self.adjustTitle)
#super(Browser).connect(self.ui.webView,QtCore.SIGNAL("titleChanged (const QString&)"), self.adjustTitle)
def load(self,url):
self.setUrl(QUrl(url))
def adjustTitle(self):
self.setWindowTitle(self.title())
app = QApplication(sys.argv)
view = Browser()
view.showMaximized()
view.load("https://duckduckgo.com")
app.exec_()
However, this is what I get:
Can someone please tell me where I am going wrong? Note that it is not a problem of the website. I have tried it with Wikipedia, Stack Overflow and Google. I am using PyQt5 version 5.10.1.
In case you want fullscreen, you have to use:
class Browser(QWebView):
def __init__(self):
# QWebView
self.view = QWebView.__init__(self)
#self.view.setPage(MyBrowser())
self.setWindowTitle('Loading...')
self.titleChanged.connect(self.adjustTitle)
self.showFullScreen()
class Browser(QWebView):
def __init__(self):
super().__init__()
def load(self, url):
self.setUrl(QUrl(url))
def adjustTitle(self):
self.setWindowTitle(self.title())
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Browser()
window.setWindowTitle('Loading...')
window.titleChanged.connect(window.adjustTitle)
window.load("https://duckduckgo.com")
window.showMaximized()
sys.exit(app.exec_())
The program does not know the real sizes of your device so it creates a maximum on its assumed geometry.
You should provide the actual geometry by resize then call showMaximized. So that your geometry will be reachable by the program and a true maximized window will be displayed.
self.resize(998, 878)
self.showMaximized()

itemClicked in QlistWidget, function executed more than 1 time

I have a strange problem, hope someone can clear it for me
import os
from os import path
import sys
import pathlib
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget,
QWizard, QWizardPage, QLineEdit, \
QTabWidget, QApplication,
QTextEdit,QToolTip,QPushButton,QMessageBox
from PyQt5.QtCore import QSize,pyqtSlot,pyqtProperty
from PyQt5.QtGui import QFont
from PyQt5.uic import loadUiType
app = QApplication(sys.argv)
if getattr(sys, 'frozen', False):
# we are running in a bundle
installPath = sys._MEIPASS
print('we are running in a bundle')
else:
# we are running in a normal Python environment
installPath = os.path.dirname(os.path.abspath(__file__))
print('we are running in a normal Python environment')
UI_File, _ = loadUiType(path.join(path.dirname(__file__), 'test.ui'))
class MainAPP(QTabWidget, UI_File):
def __init__(self, parent=None):
super(MainAPP, self).__init__(parent)
self.setupUi(self)
self.handle_buttons()
def handle_buttons(self):
self.pushButton.clicked.connect(self.test_2)
def test_2(self):
for i in range(10):
self.listWidget.addItem(str('lklk'))
self.listWidget.itemClicked.connect(self.test)
def test(self):
for i in range(10):
self.listWidget_2.addItem(str('DDD'))
self.listWidget_2.itemClicked.connect(self.test_3)
def test_3(self):
print ('hi')
def main():
app = QApplication(sys.argv)
main = MainAPP()
main.show()
app.exec_()
if __name__ == "__main__":
main()
so basically, I have a push button, if I click on it it will display some data at listWidget and if I clicked on any item in listWidget , it will display other data on ListWidget_2 and then if I click on item in List_widget_2 it then should print ('Hi')
the problem is if I click multiple times in ListWidget and then click on an item in ListWidget_2 , I received more than one ('Hi) , it will diplay ('Hi') according to the number of clicks I clicked in the Listwidget
any idea what could be the issue
You only need to make a connection between a signal and a slot once. Currently you are making additional connections each time you click an item in the first list widget, which results in your method printing "hi" executing once for every connection you made.
To fix this, make both of the signal connections either in the test_2 method or in the __init__ method

QWebEngineView - Javascript Callback

What I am ultimately trying to accomplish is to capture the username and password that the user enters into a website. For example, if the user enters "test#example.com" as the email address into Facebook's login, then clicks submit, I want to store that email address in my PyQt Application.
The closest I've come to achieving this has been using a series of JavaScript commands to place a listener on the "Login Button" that returns the current value of the user parameter. My problem is that the callback that PyQt provides is for when the runJavaScript function is completed, not the javascript event listener. I'm wondering if there is any way to capture the callback function from the JavaScript function, or if there is a better way altogether for me to do this.
import os
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from PyQt5.QtCore import QUrl, QEventLoop
from PyQt5.QtWebEngineWidgets import QWebEngineView
class WebPage(QWebEngineView):
def __init__(self):
QWebEngineView.__init__(self)
self.load(QUrl("https://facebook.com"))
self.loadFinished.connect(self._on_load_finished)
#self.page().runJavaScript("document.getElementById("myBtn").addEventListener("click", displayDate)", print)
def _on_load_finished(self):
print("Finished Loading")
cmds = ["btn=document.getElementById('u_0_r')", # Login Button
"user=document.getElementsByName('email')[0]",
"function get_username(){return user.value}",
"btn.addEventListener('click', get_username)"]
self.page().runJavaScript("; ".join(cmds), lambda x: print("test: %s" % x))
if __name__ == "__main__":
app = QApplication(sys.argv)
web = WebPage()
web.show()
sys.exit(app.exec_()) # only need one app, one running event loop
I found a work around using the "urlChanged" signal that seems to work so far for my applications
import os
import sys
from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget
from PyQt5.QtCore import QUrl, QEventLoop
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWebEngineCore import QWebEngineUrlRequestInterceptor
class WebPage(QWebEngineView):
def __init__(self):
QWebEngineView.__init__(self)
self.current_url = ''
self.load(QUrl("https://facebook.com"))
self.loadFinished.connect(self._on_load_finished)
self.urlChanged.connect(self._on_url_change)
def _on_load_finished(self):
self.current_url = self.url().toString()
def _on_url_change(self):
self.page().runJavaScript("document.getElementsByName('email')[0].value", self.store_value)
def store_value(self, param):
self.value = param
print("Param: " +str(param))
if __name__ == "__main__":
app = QApplication(sys.argv)
web = WebPage()
web.show()
sys.exit(app.exec_()) # only need one app, one running event loop

Categories