I'm using the QtWaitingSpinner found here: https://github.com/snowwlex/QtWaitingSpinner. You can create and start a spinner like so: spinner = QtWaitingSpinner(self); spinner.start()
. Unfortunately when I try to make a POST request from my GUI, the spinner halts until a response has been returned. Consequently I don't see the spinner at all, or if I start the spinner prematurely it stops spinning while it waits for the response. I think I'll have to use some sort of asynchronous method like QThread or asyncio but it's unclear what the best way of getting around this is. If anyone can show me the best way to handle it I'd be grateful. Here is a simplified version of what I'm doing:
class Obj(QDialog):
# some button calls this function when pressed
def submit(self):
#start spinner
spinner = QtWaitingSpinner(self)
spinner.start()
# post some data to some url, spinner should spin
r = requests.post('some_url.com', json=some_data)
# stop spinner
spinner.stop()
The problem you are requests
is blocking the Qt loop, so elements like QTimer
do not work. One solution is to run that task on another thread, a simple way to do it is using QRunnable
and QThreadPool
.
class RequestRunnable(QRunnable):
def __init__(self, url, json, dialog):
QRunnable.__init__(self)
self.mUrl = url
self.mJson = json
self.w = dialog
def run(self):
r = requests.post(self.mUrl, json=self.mJson)
QMetaObject.invokeMethod(self.w, "setData",
Qt.QueuedConnection,
Q_ARG(str, r.text))
class Dialog(QDialog):
def __init__(self, *args, **kwargs):
QDialog.__init__(self, *args, **kwargs)
self.setLayout(QVBoxLayout())
btn = QPushButton("Submit", self)
btn.clicked.connect(self.submit)
self.spinner = QtWaitingSpinner(self)
self.layout().addWidget(btn)
self.layout().addWidget(self.spinner)
def submit(self):
self.spinner.start()
runnable = RequestRunnable("https://api.github.com/some/endpoint",
{'some': 'data'},
self)
QThreadPool.globalInstance().start(runnable)
@pyqtSlot(str)
def setData(self, data):
print(data)
self.spinner.stop()
self.adjustSize()
A complete example can be found in the following link