【问题标题】:PyQt5 loading spinner halts on post requestPyQt5 加载微调器在发布请求时停止
【发布时间】:2018-05-01 18:33:48
【问题描述】:

我正在使用在这里找到的 QtWaitingSpinner:https://github.com/snowwlex/QtWaitingSpinner。您可以像这样创建和启动微调器:spinner = QtWaitingSpinner(self); spinner.start()。不幸的是,当我尝试从我的 GUI 发出 POST 请求时,微调器会停止,直到返回响应。因此,我根本看不到微调器,或者如果我过早启动微调器,它会在等待响应时停止旋转。我认为我将不得不使用某种异步方法,例如 QThread 或 asyncio,但目前尚不清楚解决此问题的最佳方法是什么。如果有人能告诉我处理它的最佳方法,我将不胜感激。这是我正在做的简化版本:

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

【问题讨论】:

    标签: python pyqt python-requests pyqt4 pyqt5


    【解决方案1】:

    requests 的问题是阻塞 Qt 循环,所以像 QTimer 这样的元素不起作用。一种解决方案是在另一个线程上运行该任务,一种简单的方法是使用QRunnableQThreadPool

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

    完整的例子可以在下面的link找到

    【讨论】:

      猜你喜欢
      • 2019-05-08
      • 1970-01-01
      • 2013-03-04
      • 1970-01-01
      • 1970-01-01
      • 2018-01-08
      • 1970-01-01
      • 1970-01-01
      • 2019-01-12
      相关资源
      最近更新 更多