QWebEngineView crashes when loading a PDF - pyqt5

I am porting my small project from pyqt5 to pyqt6 which deals with displaying PDFs using QWebEngineView.
I used this PyQt5 snippet to display the PDF below:
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEngineSettings
class Window(QWidget):
def __init__(self):
super().__init__()
self.webView = QWebEngineView()
self.webView.settings().setAttribute(QWebEngineSettings.PluginsEnabled, True)
self.webView.settings().setAttribute(QWebEngineSettings.PdfViewerEnabled, True)
url = QUrl.fromLocalFile(r"C:/Users/Eliaz/Desktop/qt5cadaquesPart14.pdf")
self.webView.setUrl(url)
self.webView.show()
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec())
Now when I ported it into a PyQt6 snippet given in the code below, the program is just crashing without any error messages:
import sys
from PyQt6.QtGui import *
from PyQt6.QtCore import *
from PyQt6.QtWidgets import *
from PyQt6.QtWebEngineWidgets import QWebEngineView
from PyQt6.QtWebEngineCore import QWebEngineSettings
class Window(QWidget):
def __init__(self):
super().__init__()
self.webView = QWebEngineView()
self.webView.settings().setAttribute(QWebEngineSettings.WebAttribute.PluginsEnabled, True)
self.webView.settings().setAttribute(QWebEngineSettings.WebAttribute.PdfViewerEnabled, True)
url = QUrl.fromLocalFile(r"C:/Users/Eliaz/Desktop/qt5cadaquesPart14.pdf")
self.webView.setUrl(url)
self.webView.show()
app = QApplication(sys.argv)
ex = Window()
sys.exit(app.exec())
Before exiting though, it shows these information on the console:
qt.webenginecontext:
GL Type: desktop
Surface Type: OpenGL
Surface Profile: CompatibilityProfile
Surface Version: 4.6
QSG RHI Backend: OpenGL
Using Supported QSG Backend: yes
Using Software Dynamic GL: no
Using Multithreaded OpenGL: yes
Init Parameters:
* application-name python
* browser-subprocess-path C:\Users\Eliaz\AppData\Local\Programs\Python\Python310\lib\site-packages\PyQt6\Qt6\bin\QtWebEngineProcess.exe
* create-default-gl-context
* disable-es3-gl-context
* disable-features ConsolidatedMovementXY,InstalledApp,BackgroundFetch,WebOTP,WebPayments,WebUSB,PictureInPicture
* disable-speech-api
* enable-features NetworkServiceInProcess,TracingServiceInProcess
* enable-threaded-compositing
* in-process-gpu
* use-gl desktop
Even with the additional information above, I can't still find what's wrong with my code but I'm certain that the path of the PDFs exists.
Also, I am on Windows 10 These are the versions of PyQt6 that I have. (Updated)
PyQt6 6.3.1
PyQt6-Qt6 6.3.1
PyQt6-sip 13.4.0
PyQt6-WebEngine 6.3.1
PyQt6-WebEngine-Qt6 6.3.1
Update:
I tried updating the pyqt6 packages installed in my system to 6.3.1, and testing it in a fresh virtual box but it still crashes as seen in this GIF.

This seems to be caused by a Windows-specific bug, since eveything works as expected on Linux using both PyQt-5.15.7 and PyQt-6.1.3. It's hard to say what the cause might be, given that there's no relevant output.
As a work-around, an alternative is to use PDF.js. See here for more details:
How to render PDF using pdf.js viewer in PyQt?
But note that it may be necessary to use the legacy version with PyQt5.

Related

Auto Login Script on Android

Recently, I made an auto-login script using Selenium on my Windows for my ISP's page. (I used Firefox's Geckodriver) :
`
from selenium import webdriver
from time import sleep
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.options import Options
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import warnings
warnings.filterwarnings("ignore")
url = "..."
un = "..."
pwd = "..."
options = Options()
options.binary_location = r"C:\\Program Files\\Mozilla Firefox\\firefox.exe" #my firefox binary was custom installed elsewhere
driver=webdriver.Firefox(executable_path = r'C:\\geckodriver.exe' , options=options)
driver.get(url)
# .get() generally waits for a page to load, but cannot tell why the page is taking time to load
# router login pages generally load within a second
# if they don't, then there is generally a problem with the ISP
delay = 10
print ("A period of 10 seconds will be given for the site to load in case of a slow connection.")
print ("...")
sleep (6)
try:
WebDriverWait(driver, delay).until(EC.presence_of_element_located((By.ID, 'templatemo_wrapper'))) #common ID b/w log in & logged in page
except TimeoutException:
print ("Loading took too much time! Maybe your connection is not right")
try :
driver.find_element(By.NAME, "Username").send_keys(un)
driver.find_element(By.NAME, "Password").send_keys(pwd)
driver.find_element(By.ID, "submit_btn").click()
print("Done Logging In !!!")
sleep (6)
except NoSuchElementException :
print ("Already Logged In.")
sleep (6)
My next target is to automate my ISP login page on Android. But I cannot figure out how to do that. I made a simple application using Kivy (since Kivy is based on Python).
from kivymd.app import MDApp
from kivymd.uix.screen import Screen
from kivymd.uix.dialog import MDDialog
from kivymd.uix.button import MDRoundFlatButton, MDFlatButton
from kivy.lang import Builder
screen_helper = """
Screen:
BoxLayout:
orientation:"vertical"
MDTopAppBar:
title: "Login App"
elevation: 5
MDLabel:
"""
class Loginapp(MDApp):
def build(self):
self.theme_cls.primary_palette = "Blue"
screen = Screen()
button = MDRoundFlatButton(text="Login", pos_hint={"center_x": 0.5, "center_y": 0.5},
on_release=self.showresult)
titlebar = Builder.load_string(screen_helper)
screen.add_widget(button)
screen.add_widget(titlebar)
return screen
def showresult(self, obj):
# the connection STATUS would go to the MDDialog(text portion)
close_btn = MDFlatButton(text="Close", on_release=self.closedialog)
self.dlg = MDDialog(title="Connection Status :", text = ""
size_hint=(0.7, 1), buttons=[close_btn])
self.dlg.open()
def closedialog(self, obj):
self.dlg.dismiss()
Loginapp().run()
`
Here are the images of my App :
Login Page of App &
Result Page of App
The problem lies here :
In my Windows script, I had to specify my geckodriver location, my Python version etc. But how do I do that on Android (I use Chrome on Android)? Also, will the packages that worked on Windows work on Android despite using Kivy?
I must specify here that I am currently learning Kivy / Selenium. Really a beginner here.
I could not find any conclusive result on googling :(
Thanks to anyone who helps me out here :)

Getting the error in python selenium testing for login and logout functionality

I am getting the error as...
AttributeError: 'LoginTestCase' object has no attribute 'driver'
And the code is
from selenium import webdriver;
from selenium.webdriver.common.keys import Keys
import time
import unittest
class LoginTest(unittest.TestCase):
#classmethod
def setUpclass(cls):
cls.driver = webdriver.Firefox("D:/Frontend/18-01-2021/selenium-testing")
cls.driver.implicitly_wait(10)
cls.driver.maximize_window()
def test_login_valid(self):
self.driver.get("http://localhost:4200")
self.driver.find_element_by_name("username").send_keys("admin")
self.driver.find_element_by_name("password").send_keys("admin#123")
self.driver.find_element_by_id('log').click()
self.driver.find_element_by_id('ab').click()
self.driver.find_element_by_id('usersinfo').click()
self.driver.find_element_by_id('log_out').click()
time.sleep(8)
#classmethod
def tearDownClass(cls):
cls.driver.close()
cls.driver.quit()
print("Test Completed")
I have built the above code for testing login to functionality using selenium with python unit testing .
But while executing the python code showing some errors as
AttributeError: 'LoginTestCase' object has no attribute 'driver'
Can anyone help me regarding this
There are some typos in your code:
setUpclass should be setUpClass
the test method is not indented correctly.
I think that fixing the setUpClass typo will get you going.

Selenium is not calling the website

I'm trying selenium for the first time. My code is as follows:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import selenium.webdriver.support.ui as ui
import selenium.webdriver.support.expected_conditions as EC
import os
import time
class expediaUnitTest():
def __init__(self):
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors')
dir_path=os.getcwd()
chromedriver=dir_path+"\chromedriver"
os.environ["webdriver.chrome.driver"]=chromedriver
driver=webdriver.Chrome(chrome_options=options,executable_path=chromedriver)
def timerPractice(self):
time.sleep(5)
def gotoexpedia(self):
self.driver.get("https://www.expedia.com/")
def teardown(self):
self.driver.close()
if __name__=="__main__":
obj=expediaUnitTest()
obj.gotoexpedia()
A new chromebrowser is called but it does not access the webpage. I get the errormessage:
AttributeError: 'expediaUnitTest' object has no attribute 'driver'
When i give the timePractise(), it works perfectly,as in the browser disappears after the given number of seconds. But it does not seem to be calling a function.
Ps: I'm following the online tutorial given here:https://www.youtube.com/watch?v=zZjucAn_JYk
He doesn't have the problem that I'm having.
Can someone please help?
You are missing self when creating the instance of the driver. So instead of
driver=webdriver.Chrome(chrome_options=options,executable_path=chromedriver)
it should be
self.driver=webdriver.Chrome(chrome_options=options,executable_path=chromedriver)
(in the video they are doing it exactly that way)

PyQt and Qt Designer

This is a minor problem but it irritates me
I use PyQt
I use Qt Designer
I use PyUic5 to generate the Ui_MyDialog from the output of the Qt designer
I created a custom widget and a plugin and managed to operate an insertion
of my custom widget to a dialog
I managed to operate the dialog and see my custom widget in action.
The problem is that in the Ui_MyDialog.py that is generated by the PyUic5 there
is (at the end of the file) an import for my custom widget and the file name of my custom widget is in lowercase letters and not the way the file is
I looked in the plugin and there is no place where such a filename is declared
What can be the problem?
I gave here the whole file. The problem is in the last line
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'Ui\PlotDialog.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_PlotDialog(object):
def setupUi(self, PlotDialog):
PlotDialog.setObjectName("PlotDialog")
PlotDialog.resize(400, 300)
self.horizontalLayout = QtWidgets.QHBoxLayout(PlotDialog)
self.horizontalLayout.setObjectName("horizontalLayout")
self.myQtPlotContainer = MyQtPlotConteiner(PlotDialog)
self.myQtPlotContainer.setObjectName("myQtPlotContainer")
self.horizontalLayout.addWidget(self.myQtPlotContainer)
self.buttonBox = QtWidgets.QDialogButtonBox(PlotDialog)
self.buttonBox.setOrientation(QtCore.Qt.Vertical)
self.buttonBox.setStandardButtons (QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.horizontalLayout.addWidget(self.buttonBox)
self.retranslateUi(PlotDialog)
self.buttonBox.accepted.connect(PlotDialog.accept)
self.buttonBox.rejected.connect(PlotDialog.reject)
QtCore.QMetaObject.connectSlotsByName(PlotDialog)
def retranslateUi(self, PlotDialog):
_translate = QtCore.QCoreApplication.translate
PlotDialog.setWindowTitle(_translate("PlotDialog", "Dialog"))
self.myQtPlotContainer.setToolTip(_translate("PlotDialog", "The current time"))
self.myQtPlotContainer.setWhatsThis(_translate("PlotDialog", "The analog clock widget displays the current time."))
from myqtplotconteiner import MyQtPlotConteiner

How debuging twisted application in PyCharm

I would like to debug a Twisted Application in PyCharm
from twisted.internet import defer
from twisted.application import service, internet
from txjason.netstring import JSONRPCServerFactory
from txjason import handler
class Example(handler.Handler):
def __init__(self, who):
self.who = who
#handler.exportRPC("add")
#defer.inlineCallbacks
def _add(self, x, y):
yield
defer.returnValue(x+y)
#handler.exportRPC()
def whoami(self):
return self.who
factory = JSONRPCServerFactory()
factory.addHandler(Example('foo'), namespace='bar')
application = service.Application("Example JSON-RPC Server")
jsonrpcServer = internet.TCPServer(7080, factory)
jsonrpcServer.setServiceParent(application)
How to run app from command line I know, but how to start debugging in PyCharm can't understand
Create a new Run Configuration in PyCharm, under the "Python" section.
If you start this application using twistd, then configure the "Script" setting to point to that twistd, and the "script parameters" as you would have them on the command line. You'll probably want to include the --nodaemon option.
You should then be able to Run that under PyCharm, or set breakpoints and Debug it.