模擬提交API數據Pyqt版

其實這個模擬提交數據以前已經寫過篇:html

Python requests模擬登陸

 

由於如今在作的項目中須要一個debug請求調試API,用PHP的CURL寫了一個,又因Pyqt更能直觀靈活的顯示請求的參數及獲取的響應參數。因此就更新完善了下以前寫 Python requests模擬登陸python

以前這篇用的是Python2.7版本,如今用的是Python3.5的版本從新。多線程

其實就是Pyqt4與Pyqt5直接引用模塊不一樣的關係,PyQt4的QtGui模塊,在PyQt5中被拆分紅三個模塊:QtGui,QtPrintSupport和QtWidgets。app

還有一個就是信號槽的變化ide

老式的信號和槽
PyQt4的舊式的信號和槽再也不被支持。所以如下用法在PyQt5中已經不能使用:函數

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

全部那些含有參數,而且對返回結果調用SIGNAL()或SLOT()的方法再也不被支持。綁定信號與調用函數老是等效的。
此外,另外一個差別是增長了下面的函數:
disconnect() 斷開全部對 QObject實例的鏈接,不須要參數。
新風格的信號和槽
QT實現的信號與一個可選的參數做爲兩個獨立的信號,一個與論點 和一個沒有它。PyQt4暴露這兩容許你鏈接到他們每一個 。然而,當發射信號,你必須使用適當的參數 發出的信號數。
PyQt5暴露惟一的信號在全部指定參數。然而它 容許任何可選參數被省略時,發射信號。
不一樣於PyQt4,PyQt5支持在類中自定義屬性、信號與槽,即便這個類沒有繼承自QObject(好比:混合類)。oop

參考: http://www.mamicode.com/info-detail-456379.html佈局

舉幾個Pyqt5信號槽例子:post

內置信號槽的使用

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)  
  
        ##斷開sin一、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/45196207ui

 

以上都是參考牛人示例,下面是修改過的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_())

 

運行效果:

相關文章
相關標籤/搜索