其實這個模擬提交數據以前已經寫過篇:html
由於如今在作的項目中須要一個debug請求調試API,用PHP的CURL寫了一個,又因Pyqt更能直觀靈活的顯示請求的參數及獲取的響應參數。因此就更新完善了下以前寫 Python requests模擬登陸python
以前這篇用的是Python2.7版本,如今用的是Python3.5的版本從新。多線程
其實就是Pyqt4與Pyqt5直接引用模塊不一樣的關係,PyQt4的QtGui模塊,在PyQt5中被拆分紅三個模塊:QtGui,QtPrintSupport和QtWidgets。app
還有一個就是信號槽的變化ide
老式的信號和槽
PyQt4的舊式的信號和槽再也不被支持。所以如下用法在PyQt5中已經不能使用:函數
全部那些含有參數,而且對返回結果調用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()
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_())
運行效果: