Implementing web inspection in browser using PyQt5 - python-3.x

QtWebKit is no longer supported in PyQt5.
Although there are alternates to some of the classes of QtWebKit in QtWebEngineWidgets. But, i couldn't find any alternate to the QWebInspector class that is available in PyQt4.
Are there any such classes OR even any other option so that i can implement web inspector using PyQt5 ?
Edit: Qt5.6 and beyond has removed QtWebKitWidgets

I was somewhat surprised to find that QtWebKit is making a comeback. It is still not part of Qt-5.6 or Qt-5.7, but it seems that it may continue to be maintained as separate project. This means PyQt5 can continue to support QtWebKit, even though the official Qt5 docs say it has been removed.
Depending on your platform, this probably means you will need to install some extra packages if you want to use the "new" QtWebKit module in PyQt5.
PS:
As for QtWebEngine - if you're using ubuntu/debian, it seems you will have to wait for it to be supported. See Bug #1579265.

I show the following example to use QWebInspector in PyQt5 version 5.7.1
from PyQt5.QtCore import QUrl
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtWebKitWidgets import QWebView, QWebInspector
from PyQt5.QtWidgets import QApplication, QSplitter, QVBoxLayout, QWidget
class Window(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.view = QWebView(self)
self.view.settings().setAttribute(
QWebSettings.DeveloperExtrasEnabled, True)
self.inspector = QWebInspector()
self.inspector.setPage(self.view.page())
self.inspector.show()
self.splitter = QSplitter(self)
self.splitter.addWidget(self.view)
self.splitter.addWidget(self.inspector)
layout = QVBoxLayout(self)
layout.addWidget(self.splitter)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = Window()
window.view.load(QUrl('http://www.google.com'))
window.show()
sys.exit(app.exec_())

Related

QPainter/Python - Graphic display issue [duplicate]

I notice that when I use a QPixmap inside a QLabel, seemingly random pixels (possibly based on memory) are written to the QPixmap. Why is this, and how can this be fixed? Is this just a problem with my computer? (I use Windows 7, by the way.)
import sys
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QApplication, QLabel
class BugTest(QLabel):
def __init__(self):
super().__init__()
self.setPixmap(QPixmap(200, 200))
self.show()
app = QApplication(sys.argv)
widget = BugTest()
app.exec_()
The documentation says:
Warning: This will create a QPixmap with uninitialized data. Call fill() to fill the pixmap with an appropriate color before drawing onto it with QPainter.
That means it may contain junk. If you want it to be all black, fill it with black.

PyQt5 GUI freeze caused by Windows focus-follows-mouse

When Windows focus-follows-mouse-without-raising-the-window is enabled by either of the two methods linked to below, I consistently get PyQt5 GUI 'freezes' where you have to type any character in the terminal that you ran python from in order to unfreeze the GUI; complete description and test case (Windows 10, Python 3.6.1, PyQt5) is here: pyqt5 click in terminal causes GUI freeze
To enable the focus-follows-mouse-without-raise behavior, try either of these - they both work in Windows 10:
downloadable program ('X-Mouse' though that name is used by other programs):
https://joelpurra.com/projects/X-Mouse_Controls/
registry hack description:
https://sinewalker.wordpress.com/2010/03/10/ms-windows-focus-follows-mouse-registry-hacks/
So - a few questions:
can anyone reproduce the issue? It seems 100% reproducible for me, but it would be great to hear the same from someone else.
is there a way to change the python code to detect-and-circumvent focus-follows-mouse, or just to be immune to it, i.e. maybe by ensuring the GUI application always takes focus back again when you - for example - click in a dialog or qmessagebox owned by the main GUI window, or by some other means? (Is the object hierarchy set up optimally, and if not, maybe this could all be resolved by correcting the ownership structure?)
The brute-force solution seems to work, though I'd like to leave this question open to see if someone knows of a more optimal solution; it took a fair amount of searching to figure out the right way; mainly by taking a look a the open-source code for X-Mouse. Basically, this method takes effect immediately, whereas the registry hack doesn't take effect until reboot.
New version of pyqt_freeze_testcase.py (the file from the referenced stackoverflow question); the changes are only additions, noted between lines of hash marks:
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
####################### added begin:
import win32gui
import win32con
####################### added end
# import the UI file created with pyuic5
from minimal_ui import Ui_Dialog
class MyWindow(QDialog,Ui_Dialog):
def __init__(self,parent):
QDialog.__init__(self)
self.parent=parent
self.ui=Ui_Dialog()
self.ui.setupUi(self)
################################# added begin:
self.initialWindowTracking=False
try:
self.initialWindowTracking=win32gui.SystemParametersInfo(win32con.SPI_GETACTIVEWINDOWTRACKING)
except:
pass
if self.initialWindowTracking:
print("Window Tracking was initially enabled. Disabling it for now; will re-enable on exit.")
win32gui.SystemParametersInfo(win32con.SPI_SETACTIVEWINDOWTRACKING,False)
################################# added end
def showMsg(self):
self.really1=QMessageBox(QMessageBox.Warning,"Really?","Really do stuff?",
QMessageBox.Yes|QMessageBox.No,self,Qt.WindowTitleHint|Qt.WindowCloseButtonHint|Qt.Dialog|Qt.MSWindowsFixedSizeDialogHint|Qt.WindowStaysOnTopHint)
self.really1.show()
self.really1.raise_()
if self.really1.exec_()==QMessageBox.No:
print("nope")
return
print("yep")
################################## added begin:
def closeEvent(self,event):
if self.initialWindowTracking:
print("restoring initial window tracking behavior ("+str(self.initialWindowTracking)+")")
win32gui.SystemParametersInfo(win32con.SPI_SETACTIVEWINDOWTRACKING,self.initialWindowTracking)
################################## added end
def main():
app = QApplication(sys.argv)
w = MyWindow(app)
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()

QtReactor Closes Application Window (Using Scrapy)

I have setup a basic QT (PyQt4) application. It runs a couple of spiders using Scrapy and to avoid blocking the gui during what is a pretty lengthy scraping operation, I am using QtReactor (as I saw mentioned in a couple of places) to allow my GUI to update during scraping.
Right now I just have a spinning progress bar (range of 0,0) and it updates during scraping.
I have an issue, however, that once scraping is completing my application is exiting of its own accord. It's definitely related to QtReactor as without the first two lines of code added below, it works fine (but blocks GUI).
What's causing this?
Thanks.
My Main:
from qtreactor import pyqt4reactor
pyqt4reactor.install()
import sys
from PyQt4 import QtGui
from Gui.DkMainWindow import DkMainWindow
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
form = DkMainWindow()
form.show()
sys.exit(app.exec_())
I have never used QtReactor, but all the examples I have seen do the install after creating the application:
import sys
from PyQt4 import QtGui
from Gui.DkMainWindow import DkMainWindow
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
from qtreactor import pyqt4reactor
pyqt4reactor.install()
form = DkMainWindow()
form.show()
sys.exit(app.exec_())
But if that makes no difference, you might also want to try:
app.setQuitOnLastWindowClosed(False)

pyqt+maya = fatal error when click to context menu

i use pyqt in autodesk maya. all work but when i try connect a context menu to my elements - maya get fatal error and closed.
import maya.OpenMayaUI as mui
import maya.api.OpenMaya as om
import sip
from PyQt4 import QtGui, QtCore, uic
#----------------------------------------------------------------------
def getMayaWindow():
ptr = mui.MQtUtil.mainWindow()
return sip.wrapinstance(long(ptr), QtCore.QObject)
#----------------------------------------------------------------------
form_class, base_class = uic.loadUiType('X:/tools/Maya/windows/2014/python/UI/perforceBrowserWnd.ui')
#----------------------------------------------------------------------
# main window class
#----------------------------------------------------------------------
class PerforceWindow(base_class, form_class):
def __init__(self, parent=getMayaWindow()):
super(base_class, self).__init__(parent)
self.setupUi(self)
# Popup Menu is not visible, but we add actions from above
self.popMenu = QtGui.QMenu( self )
self.popMenu.addAction("revert", self.on_action_revert)
self.popMenu.addAction("submit", self.on_action_submit)
self.filesListWgt.customContextMenuRequested.connect( self.filesListWgtMenuRequested )
#------------------------------------------------------------------
def filesListWgtMenuRequested(self, pos):
self.popMenu.exec_( self.filesListWgt.mapToGlobal(pos) )
def on_action_revert(self):
print('on_action_revert')
def on_action_submit(self):
print('on_action_submit')
#----------------------------------------------------------------------
# window
#----------------------------------------------------------------------
def perforceBrowser2():
perforceBrowserWnd = PerforceWindow()
perforceBrowserWnd.show()
perforceBrowser2()
dialog created in qtdesigner. i set attribute contentMenuPolicy in designer on QListWidtet. when i right click on QListWidtet or any element - i see a context menu. but if i click a menu or dismiss it - maya get fatal error
and i see log text - function on_action_revert is called. but after that - maya crashed.
what i doing wrong?
update:
i try simple test. replace a menu to simple call a function:
replace connect to:
self.filesListWgt.customContextMenuRequested.connect( self.on_action_revert )
def on_action_revert(self):
print('on_action_revert')
this crash maya too
I tested your code along with your UI file on PyQt in Maya 2013 as well as on PySide (using a QtShim) on Maya 2014 and your code ran fine. Please check your PyQt build for Maya 2014.
I recommend attempting to run your code using PySide on Maya 2014. To do this you do not need to change any of your code base. You just need to modify a few imports. It is worth checking out these: Take a look at this. You can use this to write code that is compatible in both PyQt and PySide. https://github.com/rgalanakis/practicalmayapython/blob/master/src/chapter5/qtshim.py
And to load your ui file in PySide environment take a look at this article: http://www.jason-parks.com/artoftech/?p=579
PyQt and PySide are both just python wrappers for the Qt framework. They are identical apart from a very few differences. So your code base never needs to change no matter what you use to run it in.
P.s. But for whatever reason you are so particular for using PyQt for 2014, Please use these guides to build it: http://download.autodesk.com/us/support/files/maya_documentation/pyqtmaya2014.pdf and this one: http://around-the-corner.typepad.com/adn/2013/04/building-sip-and-pyqt-for-maya-2014.html
Maya specific PyQt builds are maintained in this Github repo maintained by Marcus Ottosson. You can grab the specific build for yourself and add it to PYTHONPATH. I had the same issue in Maya 2015 and this helped.
https://github.com/pyqt

Alternative for tkinter's askopenfilename

Currently I am using tkinter's askopenfilename in a quicklist editor for Ubuntu to get a file's name and location. Although it works fine, the look and feel is not native.
Is there an easy alternative dialogue window, to navigate and get a file's name and location?
You could try with wxPython FileDialog:
>>> import wx
>>> d = wx.FileDialog(None)
>>> d.ShowModal()
5101
>>>
It gives a more OS specific look
wxPython is arriving soon to py3k as the Phoenix project and there are already snapshots for windows and mac (see my comment below). If you want something more stable you can use pyQt QtGui.QFileDialog.
import sys
from PyQt4 import QtGui
class Dialog(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
filename = QtGui.QFileDialog.getOpenFileName()
print filename
app = QtGui.QApplication(sys.argv)
dialog = Dialog()
You have a more complete example here.
Zenity
Zenity's File Selection Dialog provides an easy and natively looking solution with the --file-selection option. The dialog provides a number of options.
See also Zenity's man pages.
In its simplest form:
#!/usr/bin/env python3
import subprocess
try:
file = subprocess.check_output(["zenity", "--file-selection"]).decode("utf-8").strip()
print(file)
except subprocess.CalledProcessError:
pass
Gtk's FileChooserDialog
Another option is Gtk's FileChooserDialog, which produces, as one might expect, perfectly natively looking file chooser dialog windows.

Resources