How to enable incognito mode in PyQtWebEngine? - python

I am making a web browser using PyQtWebEngine but how will I give the feature of incognito mode in it.

The answer is in the example that I already pointed out in a previous post: WebEngine Widgets Simple Browser Example. In the Implementing Private Browsing section they point out that it is enough to provide a QWebEngineProfile() different from QWebEngineProfile::defaultProfile() since the latter is shared by all pages by default, which is what is not searched for in a private browsing.
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
class WebView(QtWebEngineWidgets.QWebEngineView):
def __init__(self, off_the_record=False, parent=None):
super().__init__(parent)
profile = (
QtWebEngineWidgets.QWebEngineProfile()
if off_the_record
else QtWebEngineWidgets.QWebEngineProfile.defaultProfile()
)
page = QtWebEngineWidgets.QWebEnginePage(profile)
self.setPage(page)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
view = WebView(off_the_record=True)
view.load(QtCore.QUrl("https://www.qt.io"))
view.show()
sys.exit(app.exec_())

Related

QWebEngineView not loading with default Windows elevation

I'm having a bizarre issue where this simple QWebEngine code runs perfectly fine as a regular user on Windows 10 (loads the page fully), but when I elevate my own default user account it stops loading the page. The progress output will go from 0->100 and not call loadFinished on the browser or show any output on the page. I've tried running it as an elevated standard Administrator built-in account and it seemed to work oddly enough.
Here's the unloaded page:
and here's it working properly:
Running with os.environ["QT_DEBUG_PLUGINS"] = "1" doesn't show any discrepancies between the elevated and non-elevated processes.
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtWidgets import QApplication, QMainWindow
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.browser = QWebEngineView()
self.browser.setUrl(QUrl('https://www.google.com'))
self.browser.loadProgress.connect(self.on_load_progress)
self.setCentralWidget(self.browser)
self.show()
def on_load_progress(self, progress: int):
print(f'loading progress:[{progress}]...')
app = QApplication(sys.argv)
main_win = MainWindow()
app.exec()
After trying many things and going through many logs, the only partial solution I've found to this problem is adding --no-sandbox to the QApplication argument list to make the Chromium webdriver work at all. For my app this is enough but running without sandboxing is less than ideal for a broader solution.
For those interested I found the answer thanks to this thread (has a lot more relevant info than my descriptions).

How to load a Qt Designer file (.ui) in a QWizardPage using PySide2

I want to design my QWizardPages in Qt Designer and I want to load them into my Python program with PySide2. Previously I have been using PyQt5 without any problems but making the switch to PySide2 seems harder then expected.
The problem I am facing is that when I am adding a QWizardPage to my QWizard , the page is indeed added to the Wizard, but also an other (empty) page is added. I'm not able to find what I'm doing wrong so I was wondering if someone can have a look.
I have tried to add the pages with both the functions addPage() and setPage(), but they give the same results. What I also noticed is that when I explicitely set the Title of the page with setTitle(), the empty (unwanted) page gets this title, but not the page I designed in Qt Designer.
import os
import sys
from PySide2.QtWidgets import QWizard, QWizardPage, QApplication
from PySide2.QtCore import QFile
from PySide2.QtUiTools import QUiLoader
from enum import Enum
class MyWizard(QWizard):
def __init__(self):
super().__init__()
self.setPage(PageNumbers.page_one.value, PageOne(self))
class PageOne(QWizardPage):
def __init__(self, parent):
super().__init__(parent)
ui_file = os.path.join(__file__, '..', 'pageOne.ui')
file = QFile(ui_file)
file.open(QFile.ReadOnly)
loader = QUiLoader()
loader.load(file, parent)
file.close()
self.setTitle("This is another test Title")
class PageNumbers(Enum):
page_one = 1
if __name__ == '__main__':
app = QApplication(sys.argv)
wizard = MyWizard()
wizard.show()
app.exec_()
What I would expect is to have just one QWizardPage showing up with directly the Finish button. Instead I get two QWizardPages as shown in this image:
Can someone tell me what's going on?
(I get the expected result using PyQt5 with the following code: https://pastebin.com/6W2sx9M1)
The developers of PyQt implement functions to be able to create classes based on the .ui that is not implemented in Qt by default (Qt/C++ uses the MOC to do this work), but in the case of PySide2-Qt for python it does not implement it, only has the QUiLoader class that allows to create a widget based on the .ui unlike PyQt that allows filling a class.
In conclusion there is no equivalent in PySide2 of the loadUi function so you can not implement the same logic. PySide2 is not PyQt5, there are own equivalences since they use the same base but they have implementations, limitations and advantages.
Going to the practical problem, considering that the .ui is next to the .py the solution is the following:
import os
import sys
from PySide2 import QtCore, QtWidgets, QtUiTools
from enum import Enum
class PageNumbers(Enum):
page_one = 0
class MyWizard(QtWidgets.QWizard):
def __init__(self):
super().__init__()
ui_file = os.path.join(os.path.dirname(os.path.abspath(__file__)) ,'PageOne.ui')
page_one = create_widget(ui_file, self)
self.setPage(PageNumbers.page_one.value, page_one)
def create_widget(filename, parent=None):
file = QtCore.QFile(filename)
if not file.open(QtCore.QFile.ReadOnly):
return
loader = QtUiTools.QUiLoader()
widget = loader.load(file, parent)
return widget
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
wizard = MyWizard()
wizard.show()
sys.exit(app.exec_())

Grant access to Cam & Mic using Python for PyQt WebEngine

I am building a simple web app called from Python. I am using the below code. What is the easiest way to programatically grant access to the Cam & Mic when this page is loaded? I have only found C++ examples on the web and cannot find a way to do this within Python code.
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import QUrl
app = QApplication([])
view = QWebEngineView()
view.load(QUrl("https://test.webrtc.org/"))
view.show()
app.exec_()
To give permission you must use the setFeaturePermission method of QWebEnginePage, but you must do it when the view asks you to do so when it emits the featurePermissionRequested signal, this will indicate the url and the feature.
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEngineView, QWebEnginePage
from PyQt5.QtCore import QUrl
class WebEnginePage(QWebEnginePage):
def __init__(self, *args, **kwargs):
QWebEnginePage.__init__(self, *args, **kwargs)
self.featurePermissionRequested.connect(self.onFeaturePermissionRequested)
def onFeaturePermissionRequested(self, url, feature):
if feature in (QWebEnginePage.MediaAudioCapture,
QWebEnginePage.MediaVideoCapture,
QWebEnginePage.MediaAudioVideoCapture):
self.setFeaturePermission(url, feature, QWebEnginePage.PermissionGrantedByUser)
else:
self.setFeaturePermission(url, feature, QWebEnginePage.PermissionDeniedByUser)
app = QApplication([])
view = QWebEngineView()
page = WebEnginePage()
view.setPage(page)
view.load(QUrl("https://test.webrtc.org/"))
view.show()
app.exec_()
So I found out that PyQt on the Raspberry Pi does not include support for the WebEngine capabilities. Therefore the WebEngineView class in PyQt cannot be used on the Pi. (I dont really understand why it works fine on Ubuntu but not on Raspbian, but anyway...).
I started down the path of using Qt itself, but then learned you can use the following approach
os.system('chromium-browser --use-fake-ui-for-media-stream %s' % URL)
to start Chrome with access to the microphone and camera pre-granted.

How can I make link on web page in window using pyqt4?

I have a problem.
Can I make a link on the web page in the window and when the user clicks on it, the web page will be open in the browser.
For example:
import sys
from PyQt4 import QtGui, QtCore
app = QtGui.QApplication(sys.argv)
main = QtGui.QWidget()
main.setGeometry(200, 200, 200, 100)
label = QtGui.QLabel('Stackoverflow/')
box = QtGui.QVBoxLayout()
box.addWidget(label)
main.setLayout(box)
main.show()
sys.exit(app.exec_())
Is it really?
It is of course good that you found answer, but there is special class, which allows you to open URL in default browser or files in default editors/players etc. It is QDesktopServices. For example:
from PyQt5.QtGui import QDesktopServices
from PyQt5.QtCore import QUrl
class MainWindow(QMainWindow, Ui_MainWindow):
def link(self, linkStr):
QDesktopServices.openUrl(QUrl(linkStr))
def __init__(self):
super(MainWindow, self).__init__()
# Set up the user interface from Designer.
self.setupUi(self)
self.label.linkActivated.connect(self.link)
self.label.setText('Stackoverflow/')
This example is definitely larger, but you should know about QDesktopServices, because it is very useful class.
Sorry. I have already searched the answer.
label.setText('Link')
label.setOpenExternalLinks(True)

Accessing QTextHtmlImporter in PyQt4

I'm writing a cross platform app in PyQt4. For a particular feature, I would like to access the QTextHtmlImporter class of Qt4. There is no direct python adapter class available in PyQt4. The class is part of the src/gui/text/qtextdocumentfragment_p.h file. Is there any way I can access that in Python?
I would like to modify QTextDocument.setHtml(), which code is:
void QTextDocument::setHtml(const QString &html) {
Q_D(QTextDocument); setUndoRedoEnabled(false);
d->clear();
QTextHtmlImporter(this, html).import();
setUndoRedoEnabled(true);
}
to
void QTextDocument::setHtml(const QString &html) {
Q_D(QTextDocument);
QTextHtmlImporter(this, html).import();
}
Basically setting the HTML without clearing the history. I planned to do this by using a derived class of PyQt4's QTextDocument overriding the setHtml function. Is there any other way to do this?
QTextHtmlImporter isn't even part of the Qt4 API, so the short answer is: no, there's no way to access it in PyQt4.
You could, of course, attempt to port the code to PyQt4, but I'm guessing that would be a non-trivial task.
The question is: why do you think you need to do this?
Why can't you use QTextCursor.insertHtml or QTextDocumentFragment.fromHtml?
EDIT
Here's an example of how to set the html in a text document without clearing the undo history:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QVBoxLayout(self)
self.edit = QtGui.QTextEdit(self)
self.undo = QtGui.QPushButton('Undo')
self.redo = QtGui.QPushButton('Redo')
self.insert = QtGui.QPushButton('Set Html')
layout.addWidget(self.edit)
layout.addWidget(self.undo)
layout.addWidget(self.redo)
layout.addWidget(self.insert)
self.undo.clicked.connect(self.edit.undo)
self.redo.clicked.connect(self.edit.redo)
self.insert.clicked.connect(self.handleInsert)
self.edit.append('One')
self.edit.append('Two')
self.edit.append('Three')
def handleInsert(self):
cursor = QtGui.QTextCursor(self.edit.document())
cursor.select(QtGui.QTextCursor.Document)
cursor.insertHtml("""<p>Some <b>HTML</b> text</p>""")
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())

Categories

Resources