【问题标题】:How to set value of input(type="file") with QWebElement?如何使用 QWebElement 设置 input(type="file") 的值?
【发布时间】:2013-03-06 18:36:37
【问题描述】:

我正在尝试使用QtWebKit 模块将照片上传到vk.com。我面临的问题是无法正确填写input(type="file") 的值。这是我使用的一些相关代码:

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()

值得注意的是,由于浏览器的安全政策,文件输入的填充值不可能通过 Javascript 进行。但是,应该可以使用 Qt API,更具体地说,QWebElement::setAttribute() 方法。这就是我所做的……没有任何效果(嗯,photoInput.attribute('value') 返回预期结果,但photoInput.evaluateJavaScript('return this.value;').toString() 返回空字符串,输入的onchange 处理程序也未触发)。

设置其他属性也没问题,例如QWebElement::addClass()就像一个魅力。

任何帮助都会非常棒。
谢谢。

【问题讨论】:

    标签: qt qt4 qtwebkit qwebelement


    【解决方案1】:

    出于安全原因,setAttribute 方法可能仍然无法工作。

    但是您可以重新定义函数QWebPage::chooseFile,它应该正常打开上传对话框并返回文件名,以便它在不打开对话框的情况下返回静态文件名,并通过模拟“返回”键来激活上传输入元素。

    这似乎有效:

    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_())
    

    【讨论】:

    • 如何将 webview.event(QKeyEvent(QEvent.KeyPress, Qt.Key_Enter, Qt.NoModifier)) 翻译成它的 C++ 等价物?
    • @user9379 这应该可以:QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier); webview-&gt;event(&amp;keyEvent);
    • 我可以使用WebKit.NETCefSharp 执行此操作吗?我搜索了很多,但我找不到 QWebPagesetPage() 方法的等效对象
    • @Jack 你真的需要模拟用户输入吗?您不能使用 HttpWebRequest 手动创建 POST 查询吗? (如that
    • @alexisdm:忽略之前的评论,如何设置输入类型=当前页面打开的文件?
    猜你喜欢
    • 2013-12-31
    • 2015-07-19
    • 1970-01-01
    • 2010-10-09
    • 2016-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多