I'm trying to upload a photo to vk.com using QtWebKit module. The problem I'm facing is inability to properly fill input(type="file")
's value. Here's some related code I use:
def upload():
print 'uploading...'
photoInput = web.page().mainFrame().documentElement().findFirst('input[id="photos_upload_input"]')
assert photoInput, 'No input found'
photoInput.setAttribute('value', '/Users/elmigranto/Downloads/stuff.png')
print photoInput.evaluateJavaScript('return this.value;').toString()
It's reasonable to note, that filling value of file input is impossible from Javascript due to browser security policy. However, it should be possible using Qt API, more specifically, QWebElement
::
setAttribute()
method. And that's what I did… with no effect (well, photoInput.attribute('value')
returns expected result, but photoInput.evaluateJavaScript('return this.value;').toString()
returns empty string, input's onchange
handler is also not triggered).
Setting other attributes is no problem, for example, QWebElement
::
addClass()
works like a charm.
Any help would be super great.
Thanks.
The setAttribute
method might still not work for security reasons.
But you can redefine the function QWebPage::chooseFile
that should normally open the upload dialog and return the filename so that it returns a static file name without opening the dialog, and activate that upload by simulating a "return" key press on the input element.
This seems to work:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
import sys
class WebPage(QWebPage):
def __init__(self, parent = None):
super(WebPage, self).__init__(parent)
self.overrideUpload = None
def chooseFile(self, originatingFrame, oldFile):
if self.overrideUpload is None:
return super(WebPage, self).chooseFile(originatingFrame, oldFile)
result = self.overrideUpload
self.overrideUpload = None
return result
def setUploadFile(self, selector, filename):
button = self.mainFrame().documentElement().findFirst(selector)
self.overrideUpload = filename
# set the focus on the input element
button.setFocus();
# and simulate a keypress event to make it call our chooseFile method
webview.event(QKeyEvent(QEvent.KeyPress, Qt.Key_Enter, Qt.NoModifier))
def upload():
print 'uploading...'
page.setUploadFile('input[id="photos_upload_input"]',
'/Users/elmigranto/Downloads/stuff.png')
# The change seems to be asynchronous, at it isn't visible
# just after the previous call
app = QApplication(sys.argv)
webview = QWebView()
page = WebPage(webview)
webview.setPage(page)
source = '''
<form action="#">
Select a file: <input type="file" id="photos_upload_input">
<input type="submit">
</form>
'''
webview.loadFinished.connect(upload)
webview.show()
webview.setHtml(source)
sys.exit(app.exec_())