zoukankan      html  css  js  c++  java
  • 模拟提交API数据Pyqt版

    其实这个模拟提交数据之前已经写过篇:

    Python requests模拟登录

    因为现在在做的项目中需要一个debug请求调试API,用PHP的CURL写了一个,又因Pyqt更能直观灵活的显示请求的参数及获取的响应参数。所以就更新完善了下之前写 Python requests模拟登录

    之前这篇用的是Python2.7版本,现在用的是Python3.5的版本重新。

    其实就是Pyqt4与Pyqt5直接引用模块不同的关系,PyQt4的QtGui模块,在PyQt5中被拆分成三个模块:QtGui,QtPrintSupport和QtWidgets。

    还有一个就是信号槽的变化

    老式的信号和槽
    PyQt4的旧式的信号和槽不再被支持。因此以下用法在PyQt5中已经不能使用:

    1. QObject.connect()
    2. QObject.emit()
    3. SIGNAL()
    4. SLOT()

    所有那些含有参数,并且对返回结果调用SIGNAL()或SLOT()的方法不再被支持。绑定信号与调用函数总是等效的。
    此外,另一个差异是增加了下面的函数:
    disconnect() 断开所有对 QObject实例的连接,不需要参数。
    新风格的信号和槽
    QT实现的信号与一个可选的参数作为两个独立的信号,一个与论点 和一个没有它。PyQt4暴露这两允许你连接到他们每个 。然而,当发射信号,你必须使用适当的参数 发出的信号数。
    PyQt5暴露唯一的信号在所有指定参数。然而它 允许任何可选参数被省略时,发射信号。
    不同于PyQt4,PyQt5支持在类中自定义属性、信号与槽,即使这个类没有继承自QObject(比如:混合类)。

    参考: http://www.mamicode.com/info-detail-456379.html

    举几个Pyqt5信号槽例子:

    内置信号槽的使用

    from PyQt5.QtWidgets import *  
    from PyQt5.QtCore import *  
        
    def sinTest():  
        btn.setText("按钮文本改变")  
        
    app = QApplication([])   
    main = QWidget()  
    main.resize(200,100)  
    btn = QPushButton("按钮文本",main)  
    ##按钮btn的内置信号连接名为sinTest的槽  
    btn.clicked.connect(sinTest)  
    main.show()  
    app.exec_()

    自定义信号槽的使用

    class SinClass(QObject):  
            
        ##声明一个无参数的信号  
        sin1 = pyqtSignal()  
            
        ##声明带一个int类型参数的信号  
        sin2 = pyqtSignal(int)  
            
        ##声明带一个int和str类型参数的信号  
        sin3 = pyqtSignal(int,str)  
        
        ##声明带一个列表类型参数的信号  
        sin4 = pyqtSignal(list)  
        
        ##声明带一个字典类型参数的信号  
        sin5 = pyqtSignal(dict)  
        
        ##声明一个多重载版本的信号,包括了一个带int和str类型参数的信号,以及带str参数的信号  
        sin6 = pyqtSignal([int,str], [str])  
            
        def __init__(self,parent=None):  
            super(SinClass,self).__init__(parent)  
        
            ##信号连接到指定槽  
            self.sin1.connect(self.sin1Call)  
            self.sin2.connect(self.sin2Call)  
            self.sin3.connect(self.sin3Call)  
            self.sin4.connect(self.sin4Call)  
            self.sin5.connect(self.sin5Call)  
            self.sin6[int,str].connect(self.sin6Call)  
            self.sin6[str].connect(self.sin6OverLoad)  
        
            ##信号发射  
            self.sin1.emit()  
            self.sin2.emit(1)  
            self.sin3.emit(1,"text")  
            self.sin4.emit([1,2,3,4])  
            self.sin5.emit({"name":"codeio","age":"25"})  
            self.sin6[int,str].emit(1,"text")  
            self.sin6[str].emit("text")  
                
        def sin1Call(self):  
            print("sin1 emit")  
        
        def sin2Call(self,val):  
            print("sin2 emit,value:",val)  
        
        def sin3Call(self,val,text):  
            print("sin3 emit,value:",val,text)  
        
        def sin4Call(self,val):  
            print("sin4 emit,value:",val)  
                
        def sin5Call(self,val):  
            print("sin5 emit,value:",val)  
        
        def sin6Call(self,val,text):  
            print("sin6 emit,value:",val,text)  
        
        def sin6OverLoad(self,val):  
            print("sin6 overload emit,value:",val)  
        
    sin = SinClass() 

    信号槽N对N连接、断开连接

    from PyQt5.QtWidgets import *  
    from PyQt5.QtCore import *  
      
    class SinClass(QObject):  
      
        ##声明一个无参数的信号  
        sin1 = pyqtSignal()  
      
        ##声明带一个int类型参数的信号  
        sin2 = pyqtSignal(int)  
      
        def __init__(self,parent=None):  
            super(SinClass,self).__init__(parent)  
      
            ##信号sin1连接到sin1Call和sin2Call这两个槽  
            self.sin1.connect(self.sin1Call)  
            self.sin1.connect(self.sin2Call)  
      
            ##信号sin2连接到信号sin1  
            self.sin2.connect(self.sin1)  
      
            ##信号发射  
            self.sin1.emit()  
            self.sin2.emit(1)  
      
            ##断开sin1、sin2信号与各槽的连接  
            self.sin1.disconnect(self.sin1Call)  
            self.sin1.disconnect(self.sin2Call)  
            self.sin2.disconnect(self.sin1)  
      
            ##信号sin1和sin2连接同一个槽sin1Call  
            self.sin1.connect(self.sin1Call)  
            self.sin2.connect(self.sin1Call)  
      
            ##信号再次发射  
            self.sin1.emit()  
            self.sin2.emit(1)  
      
        def sin1Call(self):  
            print("sin1 emit")  
      
        def sin2Call(self):  
            print("sin2 emit")  
      
    sin = SinClass()  

    多线程信号槽通信

    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    
    
    class Main(QWidget):
        def __init__(self, parent=None):
            super(Main, self).__init__(parent)
    
            ##创建一个线程实例并设置名称、变量、信号槽
            self.thread = MyThread()
            self.thread.setIdentity("thread1")
            self.thread.sinOut.connect(self.outText)
            self.thread.setVal(6)
            
            self.t2=MyThread()
            self.t2.setIdentity('ttt')
            self.t2.sinOut.connect(self.outText)
            self.t2.setVal(10)
    
        def outText(self, text):
            print(text)
    
    
    class MyThread(QThread):
        sinOut = pyqtSignal(str)
    
        def __init__(self, parent=None):
            super(MyThread, self).__init__(parent)
            print('b')
    
            self.identity = None
    
        def setIdentity(self, text):
            self.identity = text
            print('b1')
    
        def setVal(self, val):
            self.times = int(val)
            print('b2')
    
            ##执行线程的run方法
            self.start()
            print('c')
    
        def run(self):
            print(self.times )
            while self.times > 0 and self.identity:
                ##发射信号
                self.sinOut.emit(self.identity + " " + str(self.times))
                self.times -= 1
    
    
    app = QApplication([])
    main = Main()
    main.show()
    app.exec_()

     参考地址: http://blog.csdn.net/a359680405/article/details/45196207

    以上都是参考牛人示例,下面是修改过的Pyqt5模拟提交数据

    #!/usr/bin/python
    # -*-coding:utf-8-*-
    from PyQt5.QtWidgets import *
    from PyQt5.QtCore import *
    from PyQt5.QtGui import  QIcon
    import requests, sys
    
    # 主入口文件
    class MainWidget(QDialog):
        def __init__(self, parent=None):
            super(MainWidget, self).__init__(parent)
            self.setMinimumSize(100, 100)
            self.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowCloseButtonHint | Qt.WindowStaysOnTopHint)
            self.setWindowIcon(QIcon('favicon.ico'))
            self.setWindowTitle('模拟提交API数据PYQT版')
    
            # URL
            self.urllabel = QLabel(u'提交URL:')
            self.url = QLineEdit(u'')
            self.methodtype = QComboBox()
            self.methodtype.addItem('POST')
            self.methodtype.addItem('GET')
            self.UrlLoayout = QHBoxLayout()
            self.UrlLoayout.addWidget(self.urllabel)
            self.UrlLoayout.addWidget(self.url)
            self.UrlLoayout.addSpacing(20)  # 添加一个20px的空间距离 且不带弹性
            self.UrlLoayout.addWidget(self.methodtype)
    
            # 添加头部group
            self.headDict = {}
            self.headPostArrayKey = 0
            self.HeadGroupBox = QGroupBox(u'头部数据')
            self.HeadGroupBox.setMinimumHeight(200)  # 高度最小值
    
            self.HeadAddParam = QPushButton(u'+')
            self.headDict[str(self.headPostArrayKey) + '_key'] = QLineEdit()
            self.headDict[str(self.headPostArrayKey) + '_value'] = QLineEdit()
            self.HeadGroupBoxLayout = QGridLayout()
            self.HeadGroupBoxLayout.addWidget(self.HeadAddParam, 0, 0)
            self.HeadGroupBoxLayout.addWidget(QLabel(u'Key:'), 1, 0)
            self.HeadGroupBoxLayout.addWidget(self.headDict[str(self.headPostArrayKey) + '_key'], 1, 1)
            self.HeadGroupBoxLayout.addWidget(QLabel(u'Value:'), 1, 2)
            self.HeadGroupBoxLayout.addWidget(self.headDict[str(self.headPostArrayKey) + '_value'], 1, 3)
            self.HeadGroupBox.setLayout(self.HeadGroupBoxLayout)
            self.HeadAddParam.clicked.connect(self.addHeadParam)
    
            # 添加Body group
            self.bodyDict = {}
            self.bodyPostArrayKey = 0
            self.BodyGroupBox = QGroupBox(u'正文数据')
            self.BodyGroupBox.setMinimumHeight(200)
            self.BodyAddParam = QPushButton(u'+')
            self.bodyDict[str(self.bodyPostArrayKey) + '_key'] = QLineEdit(u'')
            self.bodyDict[str(self.bodyPostArrayKey) + '_value'] = QLineEdit(u'')
            self.BodyGroupBoxLayout = QGridLayout()
            self.BodyGroupBoxLayout.addWidget(self.BodyAddParam, 0, 0)
            self.BodyGroupBoxLayout.addWidget(QLabel(u'Key:'), 1, 0)
            self.BodyGroupBoxLayout.addWidget(self.bodyDict[str(self.bodyPostArrayKey) + '_key'], 1, 1)
            self.BodyGroupBoxLayout.addWidget(QLabel(u'Value:'), 1, 2)
            self.BodyGroupBoxLayout.addWidget(self.bodyDict[str(self.bodyPostArrayKey) + '_value'], 1, 3)
            self.BodyGroupBox.setLayout(self.BodyGroupBoxLayout)
            self.BodyAddParam.clicked.connect(self.addBodyParam)
    
            # 提交按钮
            self.btnPost = QPushButton(u'提交')
            self.postbtnLoayout = QHBoxLayout()
            self.postbtnLoayout.addStretch()
            self.postbtnLoayout.addWidget(self.btnPost)
    
            # Main布局
            main_layout = QVBoxLayout()
            main_layout.addLayout(self.UrlLoayout)
            main_layout.addWidget(self.HeadGroupBox)
            main_layout.addWidget(self.BodyGroupBox)  # addWidget 添加的是Qobject
            main_layout.addLayout(self.postbtnLoayout)  # addLayout 添加的是 Layout
    
            main_layout.setSpacing(0)
            self.setLayout(main_layout)
    
            self.btnPost.clicked.connect(self.postData)  # 点击提交按钮
    
    
            # 发送数据
    
        def postData(self):
    
            self.headdictdata = {}
            self.bodydictdata = {}
            LOOPpar1 = {'1': self.headDict.items(), 2: self.bodyDict.items()}
            LOOPpar2 = {'1': self.headdictdata, 2: self.bodydictdata}
    
            try:
                for Looptype in LOOPpar1:
                    for k, v in LOOPpar1[Looptype]:
                        temp = k.split('_')
                        if temp[1] == 'key':
                            if temp[0] in LOOPpar2[Looptype]:
                                LOOPpar2[Looptype][temp[0]]['key'] = str(v.text())
                            else:
                                LOOPpar2[Looptype][temp[0]] = {'key': str(v.text())}
    
                        elif temp[1] == 'value':
                            if temp[0] in LOOPpar2[Looptype]:
                                LOOPpar2[Looptype][temp[0]]['value'] = str(v.text())
                            else:
                                LOOPpar2[Looptype][temp[0]] = {'value': str(v.text())}
            except Exception as e:
                print(e)
            url = self.url.text()
            method = self.methodtype.currentText()
    
            if not url:
                QMessageBox.warning(self, u'notice', 'URL must fill in', QMessageBox.Yes)
                self.url.cursor()
                return False
    
            try:
                # 在 实例化类与connect、start 直接不能打印任何东西,不然会报错
                self.Theading = TheadingPost({'url': str(url), 'method': str(method), 'headdictdata': self.headdictdata,
                                              'bodydictdata': self.bodydictdata})
                self.Theading.resultJson.connect(self.updateResult)  # 连接信号。 TheadingPost在线程状态结果后emit发射信号
                self.Theading.start()  # 线程开始
            except Exception as e:
                print(e)
    
        # 返回响应的参数
        def updateResult(self, resdata):
            if resdata['status'] == 1:
                self.WChild = TextWidget()
                self.Dialog = QDialog(self)
                self.WChild.UI_init(self.Dialog)
                self.WChild.setValue(resdata['msg'])
                self.Dialog.exec_()
            else:
                QMessageBox.warning(self, u'错误提示!', str(resdata['msg']), QMessageBox.Yes)
    
        # 添加头部Data
        def addHeadParam(self):
            sts = str(self.headPostArrayKey + 1)
            self.headDict[sts + '_key'] = QLineEdit()
            self.headDict[sts + '_value'] = QLineEdit()
            self.HeadGroupBoxLayout.addWidget(QLabel(u'Key:'))
            self.HeadGroupBoxLayout.addWidget(self.headDict[sts + '_key'])
            self.HeadGroupBoxLayout.addWidget(QLabel(u'Value:'))
            self.HeadGroupBoxLayout.addWidget(self.headDict[sts + '_value'])
            self.headPostArrayKey += 1
    
        # 添加Body Data
        def addBodyParam(self):
            sts = str(self.bodyPostArrayKey + 1)
            self.bodyDict[sts + '_key'] = QLineEdit()
            self.bodyDict[sts + '_value'] = QLineEdit()
    
            self.BodyGroupBoxLayout.addWidget(QLabel(u'Key:'))
            self.BodyGroupBoxLayout.addWidget(self.bodyDict[sts + '_key'])
            self.BodyGroupBoxLayout.addWidget(QLabel(u'Value:'))
            self.BodyGroupBoxLayout.addWidget(self.bodyDict[sts + '_value'])
            self.bodyPostArrayKey += 1
    
    '''
    响应显示textWidget
    '''
    class TextWidget(object):
        def UI_init(self, textMyDialog):
            textMyDialog.resize(600, 400)
            textMyDialog.setWindowTitle("响应参数")
            self.horizontalLayout = QHBoxLayout(textMyDialog)
            self.textEdit = QTextEdit(textMyDialog)
            self.textEdit.setStyleSheet("background-color: rgb(59, 59, 59);")
            self.textEdit.setTextColor(Qt.yellow)  # 当setValue 时 设置颜色不起作用,只对为空时,输入的文字颜色改变
            self.horizontalLayout.addWidget(self.textEdit)
    
        def setValue(self, val):
            self.textEdit.setHtml("<span style='color:yellow'>" + str(val) + "</span>")
    
    # 线程提交类
    class TheadingPost(QThread):
        resultJson = pyqtSignal(dict)  # 声明一个带dict的参数信号
    
        def __init__(self, dict):
            super(TheadingPost, self).__init__()
            self.dict = dict
    
        def run(self):
            self.action = self.dict['url']
            self.headerdict = self.dict['headdictdata'].values()
            self.datadict = self.dict['bodydictdata'].values()
            self.header = {}
            for hv in self.headerdict:
                if hv['key']:
                    self.header[hv['key']] = hv['value']
            self.data = {}
            for dv in self.datadict:
                self.data[dv['key']] = dv['value']
            self.method = self.dict['method']
            result = {}
            result['status'] = 0
            try:
                returndata = self.httpRequest(self.method, self.action, self.data)
                result['status'] = 1
                result['msg'] = returndata
            except Exception as e:
                result['status'] = 2
                result['msg'] = e
    
            self.resultJson.emit(result)  ##发射信号
    
        def httpRequest(self, method, action, query=None):
            default_timeout = 10
            if (method == 'GET'):
                # url = action if (query == None) else (action + '?' + query)
                connection = requests.get(action, headers=self.header, timeout=default_timeout, params=query)
            elif (method == 'POST'):
                connection = requests.post(
                    action,
                    data=query,
                    headers=self.header,
                    timeout=default_timeout
                )
            connection.encoding = "UTF-8"
            return connection.text
    
    
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        main_widget = MainWidget()
        main_widget.show()
        sys.exit(app.exec_())

    运行效果:

  • 相关阅读:
    OGG复制同步,提示字段长度不够ORA-01704
    19c修改system,sys密码
    NFS服务端与客户端断网,导致作为NFS客户端的Oracle主机hang住
    ACFS启动报错acfsload start line 42: /lib/acfstoolsdriver.sh: No such file or directory
    OGG MAXTRANSOPS 参数
    TCP详解
    异步机制
    Linux 下创建和使用静态库
    U3D简单得换装技术
    排序
  • 原文地址:https://www.cnblogs.com/dcb3688/p/4608039.html
Copyright © 2011-2022 走看看