GrabWidget & GrabImage in QWebView with Flash Player
-
This question is also available on StackOFlow right here
There are a few methods when we want to grab an image from an application. When it comes to PyQt, there are a few options, each of them having some (dis)advantages:
Using QPixmap.grabWidget(): image = QPixmap.grabWidget(tab_a, 0, 0, -1, -1) Using QPixmap.grabWindow(): image = QPixmap.grabWidget(tab_a.winId(), 0, 0, -1, -1)
Youtube seems to be the right site to test what I want to achieve, because when you play a video you will need flash in order to play it.
If we use the grabWindow() function we can grab the image from any flash or non-flash content without any problems, because Qt uses it's magic (I think a platform-dependent way of grabbing the screen) and it does the trick. But the disadvantage is if you minimize your application you will get back black pixels. The most logical thing to me is that there is a minimized app, so the platform-dependent way for grabbing the screen sees nothing (if anyone can provide more details to do it, I don't know how to explain in any other way).
If we use the grabWidget() method, the advantage it is that we can minimize the app and still got the image, but we lose the flash content - in other words, when the app is minimized, we get an image but no flash content.
Problem 1: (not so important I can live without it) I want to use grabWidget(), which gives me the flexibility to minimize the app, and I want to save the flash content, so basically save flash content when the app is minimized.
Problem 2: (which is spinning around this subject) If I want to send a Keyboard Key or a Mouse Click in the area/location where the flash is displayed it will not work.** Qt is unable** to send either Keyboard Key or Mouse Click in flash-content via QKeyEvent or QMouseEvent.
In my hours of research here's what I found that may be useful: link to similar problem
Here I will put some code to get a quick kick Start on the issue, you will need PyQt-4.8, and Python-3.4 (that is what I'm using in this example):
from PyQt4.QtCore import * from PyQt4.QtGui import * from PyQt4.QtWebKit import * import sys class main_frame(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.initUI() def initUI(self): # Create a QTabWidget main_qtb = QTabWidget(self) main_qtb.setFixedSize(1300, 800) # Create a widget tab_a = QWidget() # Add the widget to 'main_qtb' main_qtb.addTab(tab_a, "Tab_A") ### Create some buttons ### btn_grab_img = QPushButton("Grab Img", tab_a) btn_grab_img.move(20, 740) btn_send_click = QPushButton("Send Click", tab_a) btn_send_click.move(100, 740) btn_send_key = QPushButton("Send Key", tab_a) btn_send_key.move(180, 740) btn_minimize = QPushButton("Minimize", tab_a) btn_minimize.move(260, 740) ### Create a web viewer ### web = QWebView(tab_a) url = QUrl("http://www.youtube.com") web.load(url) # Enable plugins, this will enable flash, you need to have it installed on your machine in order to work # anyway, basic stuff settings = web.settings() settings.setAttribute(QWebSettings.PluginsEnabled, True) def grab_image_wrapper(): # There are two function bellow, # One of them use PyQt-build-in-function 'grabWidget' # Another one use PyQt-build-in-function 'grabWidget' def grab_image_widget(): image = QPixmap.grabWidget(tab_a, 0, 0, -1, -1) # Save image to local computer image.save('graber_tester_Widget.jpg', "jpg", 100) print("Grab image widget activated") def grab_image_window(): image = QPixmap.grabWindow(tab_a.winId(), 0, 0, -1, -1) # Save image to local computer image.save('graber_tester_Window.jpg', "jpg", 100) print("Grab image window activated") # I use QTime just to delay it 3,4 seconds ... nothing fancy here, let`s move on ... # It is also help you to press minimize button and see the effects, # on both minimized application or normal mode (on screen) QTimer.singleShot(3000, grab_image_widget) QTimer.singleShot(4000, grab_image_window) btn_grab_img.clicked.connect(grab_image_wrapper) #..................... self.setFixedSize(1300, 800) def minimize_app(): self.showMinimized() btn_minimize.clicked.connect(minimize_app) def main(): app = QApplication(sys.argv) myapp = main_frame() myapp.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
It seems to be one of the "dark-art of flash"