【问题标题】:PyQt Webkit and html forms: Fetching output and closing windowPyQt Webkit 和 html 表单:获取输出和关闭窗口
【发布时间】:2012-09-02 22:18:02
【问题描述】:

我正在尝试获取一个无边框的 python PyQt webkit 窗口来显示单个网站 html 表单。单击发送时,表单值应保存在字典中并关闭窗口。

到目前为止(在SO 的帮助下)我有无边框窗口并且可以获取输入。但是,缺少两件事:

  1. 按发送后关闭窗口。
  2. 在字典elements 中获取输入(注意elements 的键对应于html 表单名称)。

(可能反过来会更好,但 1 似乎更难)

到目前为止我的代码是:

import sys

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *

elements = {"like":"", "text": ""}

class MyWebPage(QWebPage):
    def acceptNavigationRequest(self, frame, req, nav_type):
        if nav_type == QWebPage.NavigationTypeFormSubmitted:
            text = "<br/>\n".join(["%s: %s" % pair for pair in req.url().queryItems()])
            print(text)
            return True
        else:
            return super(MyWebPage, self).acceptNavigationRequest(frame, req, nav_type)


class Window(QWidget):
    def __init__(self, html):
        super(Window, self).__init__()
        self.setWindowFlags(Qt.FramelessWindowHint)
        view = QWebView(self)
        layout = QVBoxLayout(self)
        layout.addWidget(view)
        view.setPage(MyWebPage())
        view.setHtml(html)


# setup the html form
html = """
<form action="" method="get">
Like it?
<input type="radio" name="like" value="yes"/> Yes
<input type="radio" name="like" value="no" /> No
<br/><input type="text" name="text" value="Hello" />
<input type="submit" name="submit" value="Send"/>
</form>
"""

def main():
    app = QApplication(sys.argv)

    window = Window(html)
    window.show()
    app.exec_()

if __name__ == "__main__":
    main()

一个完美的答案不仅会显示如何(a) 保存输入(b) 关闭窗口,而且(c) 还可以删除html 页面周围剩余的灰色小边框

更新:我使用 Python 2。

【问题讨论】:

    标签: python webkit pyqt4 forms


    【解决方案1】:

    要将表单数据放入dict,最好使用python标准库中的unquote_plus,因为(与QUrl不同)它可以处理加号和百分比编码。

    要关闭窗口,您可以从网页发出formSubmitted 信号,并将其连接到主窗口上的处理程序。然后这个处理程序可以在主窗口调用close(),对表单数据进行所有处理,最后quit()应用程序。

    要移除页面周围的边框,请将主布局的contentsMargins 设置为零。

    这是实现上述想法的脚本的修订版本:

    import sys
    from urllib import unquote_plus
    
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
    from PyQt4.QtWebKit import *
    
    class MyWebPage(QWebPage):
        formSubmitted = pyqtSignal(QUrl)
    
        def acceptNavigationRequest(self, frame, req, nav_type):
            if nav_type == QWebPage.NavigationTypeFormSubmitted:
                self.formSubmitted.emit(req.url())
            return super(MyWebPage, self).acceptNavigationRequest(frame, req, nav_type)
    
    class Window(QWidget):
        def __init__(self, html):
            super(Window, self).__init__()
            self.setWindowFlags(Qt.FramelessWindowHint)
            view = QWebView(self)
            layout = QVBoxLayout(self)
            layout.addWidget(view)
            layout.setContentsMargins(0, 0, 0, 0)
            view.setPage(MyWebPage())
            view.setHtml(html)
            view.page().formSubmitted.connect(self.handleFormSubmitted)
    
        def handleFormSubmitted(self, url):
            self.close()
            elements = {}
            for key, value in url.encodedQueryItems():
                key = unquote_plus(bytes(key)).decode('utf8')
                value = unquote_plus(bytes(value)).decode('utf8')
                elements[key] = value
            # do stuff with elements...
            for item in elements.iteritems():
                print '"%s" = "%s"' % item
            qApp.quit()
    
    # setup the html form
    html = """
    <form action="" method="get">
    Like it?
    <input type="radio" name="like" value="yes"/> Yes
    <input type="radio" name="like" value="no" /> No
    <br/><input type="text" name="text" value="" />
    <input type="submit" name="submit" value="Send"/>
    </form>
    """
    
    def main():
        app = QApplication(sys.argv)
    
        window = Window(html)
        window.show()
        app.exec_()
    
    if __name__ == "__main__":
        main()
    

    【讨论】:

    • 非常感谢,看起来很棒。不幸的是,我使用 python 2。
    • @Henrik。对于那个很抱歉。现在转换为使用 python2。
    • 这太棒了。非常感谢。如果可以,我会立刻拥抱你!
    • 我尝试以一种可以连续显示两个网站的方式实现它(每次调用app.exec_())但没能做到,也许可以扩展答案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多