1

以前の質問のおかげで、htmlフォームを表示して入力をフェッチするPyQt4クラスがあります(古い質問はここにあります)。

ここで、メインループを終了し、別のことを実行して、後で別のhtmlフォームを使用してメインループを再開します。問題は、メインループの2回目の実行でイベントハンドルが機能しないことです。私は何が間違っているのですか?

問題は、フォームが送信されないため、2回目に呼び出されたMyWebPageときにクラスが正しく機能しないことであると思われます。app.exec_()

これが実行される私のコードですが、2番目のフォームを送信しません:

import sys
from urllib import unquote_plus

from PyQt4 import QtCore, QtGui, QtWebKit

class MyWebPage(QtWebKit.QWebPage):
    formSubmitted = QtCore.pyqtSignal(QtCore.QUrl)

    def acceptNavigationRequest(self, frame, req, nav_type):
        if nav_type == QtWebKit.QWebPage.NavigationTypeFormSubmitted:
            self.formSubmitted.emit(req.url())
        return super(MyWebPage, self).acceptNavigationRequest(frame, req, nav_type)



class PsyTML(QtGui.QWidget):
    def __init__(self):
        super(PsyTML, self).__init__()
        self.elements = {}
        self.view = QtWebKit.QWebView(self)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.view)
        layout.setContentsMargins(0, 0, 0, 0)
        self.view.setPage(MyWebPage())
        self.view.page().formSubmitted.connect(self.handleFormSubmitted)

    def viewPsyTML(self, html):
        self.view.setHtml(html)
        self.show()

    def handleFormSubmitted(self, url):
        elements = self.elements
        self.close()
        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
        QtGui.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>
"""

html2 = """
<form action="" method="get">
Choose wisely?
<input type="radio" name="choose" value="A"/> Yes
<input type="radio" name="choose" value="B" /> No
<br/><input type="text" name="text" value="" />
<input type="submit" name="submit" value="Send"/>
</form>
"""

def main():
    app = QtGui.QApplication(sys.argv)
    intro = PsyTML()
    intro.viewPsyTML(html)
    # now, the html form is displayed nicely and the form elemtns returned
    app.exec_()
    # do something else here

    # in the secomd run, the form is not submitted.
    intro.viewPsyTML(html2)
    app.exec_()



if __name__ == "__main__":
    main()

私はPython2を使用しています。

4

1 に答える 1

1

プログラムの現在の構造を変更する必要があります。

まず、main関数はできるだけシンプルに保つ必要があります。アプリケーション オブジェクトとメイン ウィンドウを作成し、イベント ループを実行するだけです。その後、シグナル/イベントとそのハンドラーを中心にすべてを構成する必要があります。

現在、中心となるイベントは 1 つだけです: フォームの送信です。これは非同期で行われるため、アプリケーションは現在の状態を保存し、次のタスクに移る前に各フォームが完了するのを受動的に待機する必要があります。

編集

仕様が明確になったので、目的を達成する 1 つの方法QDialogは、独自のイベント ループを持つ を使用することです。

これは、希望に近いスクリプトの改訂版です。

import sys
from urllib import unquote_plus

from PyQt4 import QtCore, QtGui, QtWebKit

class MyWebPage(QtWebKit.QWebPage):
    formSubmitted = QtCore.pyqtSignal(object)

    def acceptNavigationRequest(self, frame, req, nav_type):
        if nav_type == QtWebKit.QWebPage.NavigationTypeFormSubmitted:
            elements = {}
            for key, value in req.url().encodedQueryItems():
                key = unquote_plus(bytes(key)).decode('utf8')
                value = unquote_plus(bytes(value)).decode('utf8')
                elements[key] = value
            self.formSubmitted.emit(elements)
        return super(MyWebPage, self).acceptNavigationRequest(frame, req, nav_type)

class PsyTML(QtGui.QDialog):
    def __init__(self):
        super(PsyTML, self).__init__()
        self.elements = {}
        self.view = QtWebKit.QWebView(self)
        layout = QtGui.QVBoxLayout(self)
        layout.addWidget(self.view)
        layout.setContentsMargins(0, 0, 0, 0)
        self.view.setPage(MyWebPage())
        self.view.page().formSubmitted.connect(self.handleFormSubmitted)

    def viewPsyTML(self, html):
        self.view.setHtml(html)
        self.exec_()

    def handleFormSubmitted(self, elements):
        self.elements = elements
        self.accept()

# 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>
"""

html2 = """
<form action="" method="get">
Choose wisely?
<input type="radio" name="choose" value="A"/> Yes
<input type="radio" name="choose" value="B" /> No
<br/><input type="text" name="text" value="" />
<input type="submit" name="submit" value="Send"/>
</form>
"""

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

    intro = PsyTML()
    intro.viewPsyTML(html)

    # do stuff with elements...
    for item in intro.elements.iteritems():
        print '"%s" = "%s"' % item

    intro = PsyTML()
    intro.viewPsyTML(html2)

if __name__ == "__main__":
    main()
于 2012-09-06T23:56:24.823 に答える