Reputation: 11296
Normally, when I perform a network request via Qt 4.8 I don't need to explicitly run QApplication.processEvents()
(see this StackOverflow code example).
However when I issue the network request from JavaScript in a QWebView
, this will not work unless I call that method until the request is finished, as seen below (syntax-highlighted gist here).
CLARIFICATION:
The request is not even sent when I omit the processEvents()
call although the finished
slots seem to be attached as I understand it.
from PyQt4 import QtCore, QtGui, QtNetwork, QtWebKit
class MainWindow(QtGui.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
QtNetwork.QNetworkProxyFactory.setUseSystemConfiguration(True)
self.view = QtWebKit.QWebView(self)
self.setCentralWidget(self.view)
self.view.setPage(QtWebKit.QWebPage(self.view))
self.view.page().mainFrame().javaScriptWindowObjectCleared.connect(self.refreshJS)
self.view.setHtml(
'''<html>
<body>
LOADING...
<script>
<!--
APP.request();
//-->
</script>
</body>
</html>'''
)
@QtCore.pyqtSlot()
def request(self):
request = QtNetwork.QNetworkRequest(QtCore.QUrl('http://localhost/test.php'))
manager = QtNetwork.QNetworkAccessManager()
manager.finished.connect(self.managerFinished)
reply = manager.post(request, b'a=A')
reply.finished.connect(self.finished)
############################################################
### FIXME: Request never even *sent* if this is missing ###
############################################################
while not reply.isFinished():
QtGui.QApplication.processEvents()
##########################################################
print('request FINISHED? '+str(reply.isFinished())+', ERROR '+str(reply.error()))
def finished(self):
print('finished')
def managerFinished(self):
print('managerFinished')
def refreshJS(self):
print('refreshJS')
self.view.page().mainFrame().addToJavaScriptWindowObject('APP', self)
if __name__ == '__main__':
import os, sys
app = QtGui.QApplication(sys.argv)
MainWindow().show()
sys.exit(app.exec_())
Upvotes: 0
Views: 6670
Reputation: 986
There is one big difference between your usage of QNetworkAccessManager and one pointed in the link. Notice that your version is synchronous: you block the event loop in 'request' slot by waiting for reply, thus QNetworkAccessManager cannot work unless you push the events by hand. From the other side the pointed example is asynchronous: it creates request, connects 'finished' signal and lets event loop to work. This way event loop is not blocked and network manager works well. I understand that in your situation 'request' slot needs to be synchronous, thus processEvents is a must here.
EDIT
If you want to make the request
asynchronous, then you need to be sure that QNetworkAccessManager
object is persistent outside the request
method. Initialize it in __init__(self)
and use it to POST in the request. Probably
QNetworkReply` needs to be persistent too, you need to check it.
Upvotes: 3