V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zjty
V2EX  ›  程序员

pyqt5 中如何发 Post 请求, Python 版的

  •  
  •   zjty · 2020-07-30 13:48:01 +08:00 · 2389 次点击
    这是一个创建于 1568 天前的主题,其中的信息可能已经有所发展或是发生改变。
    class MyNetworkTest(QMainWindow):
        def __init__(self, parent = None):
            super().__init__(parent)
            self.mywidget = testnetwork.Ui_MainWindow()
            self.mywidget.setupUi(self)
            self.mywidget.pushButton.clicked.connect(self.requestNetwork)
    
        def replyFinished(self, reply):
            pass
        
        def requestNetwork(self):
            httpReq = HttpReq()
            url = 'http://localhost:8021/api/v1/getDesignTool'
            data_dict = {'seqno': '10001'}
            httpReq.request(url, data_dict, self.request_success, self.request_error)
    
    
    import sys
    import json
    import testnetwork
    
    from PyQt5.QtWidgets import *
    from PyQt5.QtNetwork import *
    from PyQt5.QtGui import *
    from PyQt5.QtCore import *
    
    
    class HttpReq(QObject):
    
        def __init__(self):
            super().__init__()
            self.onSuccess = None
            self.onFailed = None
            self.m_netAccessManager = QNetworkAccessManager()
            self.m_netReply = None
    
        def request(self, httpUrl, sendData, on_success, on_fail):
            if self.m_netReply is not None:
                self.m_netReply.disconnect()
            self.onSuccess = on_success
            self.onFailed = on_fail
    
            req = QNetworkRequest(QUrl( httpUrl))
            req.setHeader(QNetworkRequest.ContentTypeHeader, "application/x-www-form-urlencoded")
            senda = QByteArray()
            senda.append(self.convertDict(sendData))
    
            self.m_netAccessManager.finished.connect(self.readData)
            self.m_netReply = self.m_netAccessManager.post(req, senda)
    
            # eventloop = QEventLoop()
            # eventloop.exec()
            # QNetworkReply * postReply = m_pNetManager->post(request, qbt); // post 方式到本地服务器
            # connect(postReply, SIGNAL(finished()), this, SLOT(postFileReplyFinished())); // 成功后会有返回响应
            # loop->exec();
    
            # self.m_netReply.finished.connect(self.readData)
            # self.m_netReply.error.connect(self.requesterr)
    
        def readData(self):
            recvData = self.m_netReply.readAll()
            print(recvData)
            data = bytes.decode(recvData.data(), encoding='utf8')
            try:
                result = json.loads(data)
                self.onSuccess(result)
            except Exception as err:
                self.onFailed(err)
    
        def requesterr(self, err):
            self.onFailed(err)
    
        def convertDict(self, param_dict):
            param_str = ""
            index = 1
            for key, value in param_dict.items():
                if index == len(param_dict):
                    param_str += '%s%s%s' % (key, '=', value)
                else:
                    param_str = '%s%s%s%s' % (key, '=', value, '&')
                index += 1
            return param_str
    
    

    发现不在主线程上 self.m_netAccessManager.finished.connect(self.readData) 的回调不会执行 这个 QEventLoop 也不知道如何用,有用过 Pyqt5 开发的朋友提供下文章或者相关代码么,post 请求发文件和数据的相关的,谢谢

    14 条回复    2020-08-04 08:54:34 +08:00
    knva
        1
    knva  
       2020-07-30 14:29:34 +08:00   ❤️ 1
    不懂,但是 python 直接用 requests 库不行吗
    EggtartZ
        2
    EggtartZ  
       2020-07-30 15:12:08 +08:00   ❤️ 1
    QNetworkReply 的信号应该和 QEventLoop 的槽连接起来吧,不然 loop 就不出去了
    zjty
        3
    zjty  
    OP
       2020-07-30 15:37:34 +08:00
    @knva 直接用 requests 库据说会卡,没试过
    zjty
        4
    zjty  
    OP
       2020-07-30 15:39:15 +08:00
    @EggtartZ 对啊,可我不知道怎么用,边上的 connect 是 C++的,不知道怎么连接起来,最近刚学,也不知道咋整,现在直接
    ```
    eventloop = QEventLoop()
    eventloop.exec()
    ```
    没有关闭循环的,也不知道会不会有问题
    Jackeriss
        5
    Jackeriss  
       2020-07-30 15:43:36 +08:00 via iPhone   ❤️ 1
    记得有个 Qthread,你开个线程处理请求就行了
    imn1
        6
    imn1  
       2020-07-30 16:04:01 +08:00   ❤️ 1
    @zjty #3
    卡,应该不是 requests 的原因,而是数据处理运行在主线程的原因
    就算你用 QT 的模块代码,数据处理放在主线程也会卡的,除非这个处理是瞬间完毕
    开个 QThread,里面用 python 还是 pyqt5 都没所谓,不复杂,就是一个带 run 方法的类,emit 取代 return 来返回数据
    roundgis
        7
    roundgis  
       2020-07-30 16:14:59 +08:00   ❤️ 1
    @zjty 放在 thread 执行就好了
    zjty
        8
    zjty  
    OP
       2020-07-30 16:19:56 +08:00
    @knva @Jackeriss @imn1 @roundgis 嗯,放在线程里调用 requests 去请求的确可以
    EggtartZ
        9
    EggtartZ  
       2020-07-30 17:39:28 +08:00
    @zjty
    connect(m_netManager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
    eventLoop.exec();
    这是我之前写 c++的时候找的,改一下就行了
    EggtartZ
        10
    EggtartZ  
       2020-07-30 17:43:47 +08:00   ❤️ 1
    @EggtartZ
    self.m_netAccessManager.finished.connect(eventLoop.quit),没用过 PyQt5,不知道是不是这样写的
    zjty
        11
    zjty  
    OP
       2020-07-31 16:56:59 +08:00
    @EggtartZ 嗯,非常感谢
    zjty
        12
    zjty  
    OP
       2020-07-31 17:02:10 +08:00
    @EggtartZ 请问下 qt 中将 pdf 导入,然后对其进行控件堆叠,就是加一些图片和文本,再保存成 pdf,能不能做到还是矢量 pdf,就是放大缩小不失真的,我用了 fitz 模块,将 pdf 转成 image,然后堆叠了一些控件,再通过其保存成图片转成 pdf,发现拉动会模糊,原来的 pdf 是缩放不失真的,我在想是不是第一步就错了,pdf 保存成图片就会失真。望提点意见。
    EggtartZ
        13
    EggtartZ  
       2020-08-01 22:56:27 +08:00   ❤️ 1
    @zjty 不好意思,没做过这方面的工作,不了解,我觉得你想要不失真就不应该转成图片吧
    zjty
        14
    zjty  
    OP
       2020-08-04 08:54:34 +08:00
    @EggtartZ 是的,我后来就没转图片了,直接按照坐标等在 pdf 上操作了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1805 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 16:44 · PVG 00:44 · LAX 08:44 · JFK 11:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.