一、任务目标
完成HTTP接口测试,效果如下图所示:
二、窗口分析
进入Qt designer,新建Qwidget
(一)、顶部键入网址发送区
菜单栏layouts选择水平布局:
对象:horizontalLayout 类:QHBoxLayout
布局完成后,往该布局内添加选择框、编辑框和按钮:
在菜单栏input widgets、与buttons中查找:
选择框:对象:comboBox 类:QcomboBox
编辑框:对象:lineEdit 类:QlineEdit
按钮:对象:PushButton 类:QPushButton
为了方便后续的操作,我们更改了对象名,到这一步,效果如图:
(二)、消息头区与消息体区
菜单栏layouts,新加入水平布局,用来存放消息头和消息体的一大整块,如图:
那么水平布局8就是我们消息头与消息体的整个大布局,拖入两个垂直布局2、3,效果如图:
分别再往垂直布局2、3中添加水平布局,再分别在左侧垂直布局中label与两个button以及QtableWidgets,在右侧垂直布局中加入一个label与QtextEdit,最后在垂直布局3与4之间添加line,line属于水平布局8
这里因为笔者的HTTPClient整个大布局之前选择了垂直布局,所以需要在HTTPClient对象中右键->布局->打破布局,使得我们布局更加方便,避免拖不进去
为了方便获取请求头,我们需要添加Table列
(三)、响应区
使用QtextEdit即可,因为整个项目的大布局刚才已经被我们打破,这里先随便拖动设置一个大小摆放好
(四)、底部清除按钮区
添加水平布局,在水平布局内加入Push Button即可
修改清除按钮的Max大小
修改一些对象名,方便在python代码中利用
最后把祖先对象HTTPClient,也就是整个大布局更改为水平布局,得到设计效果如图:
三、代码演示
最终运行,无论如何拖动变化大小,窗口组建依然层次分明
[b]HTTPClient.ui文件:
链接:https://pan.baidu.com/s/1P_iRwFUHoPGZ_Bs_DqwkaQ
提取码:e3T1
[b]
HTTP接口测试器完整代码:
from PySide2.QtWidgets import QApplication
from PySide2.QtUiTools import QUiLoader
from PySide2.QtCore import QObject
from PySide2.QtGui import QIcon
import traceback
import requests
class HttpClient(QObject):
def __init__(self):
QObject.__init__(self)
# 从 UI 定义中动态 创建一个相应的窗口对象
self.ui = QUiLoader().load('httpclient.ui')
# 给 boxMethod 添加选项 GET POST PUT DELETE
self.ui.boxMethod.addItems(
['GET', 'POST', 'PUT', 'DELETE' ])
# 让 表格控件宽度随着父窗口的缩放自动缩放
self.ui.headersTable.horizontalHeader().setStretchLastSection(True)
# 设定第1列的宽度为 180像素
self.ui.headersTable.setColumnWidth(0, 180)
# 信号处理:发送请求
self.ui.buttonSend.clicked.connect(self.sendRequest)
# 信号处理:添加消息头
self.ui.buttonAddHeader.clicked.connect(self.addOneHeader)
# 信号处理:删除消息头
self.ui.buttonDelHeader.clicked.connect(self.delOneHeader)
def addOneHeader(self):
# rowCount = self.ui.headersTable.rowCount()
# 要插入的行始终是当前行 的下一行
addRowNumber = self.ui.headersTable.currentRow() + 1
self.ui.headersTable.insertRow(addRowNumber)
def delOneHeader(self):
self.ui.headersTable.removeRow(
self.ui.headersTable.currentRow()
)
def sendRequest(self):
method = self.ui.boxMethod.currentText()
url = self.ui.editUrl.text()
payload = self.ui.editBody.toPlainText()
# 获取消息头
headers = {}
ht = self.ui.headersTable
for row in range(ht.rowCount()):
k = ht.item(row,0).text()
v = ht.item(row,1).text()
if k.strip() == '':
continue
headers[k] = v
req = requests.Request(method,
url,
headers=headers,
data=payload
)
prepared = req.prepare()
self.pretty_print_request(prepared)
s = requests.Session()
try:
r = s.send(prepared)
self.pretty_print_response(r)
except:
self.ui.outputWindow.append(
traceback.format_exc())
def pretty_print_request(self,req):
if req.body == None:
msgBody = ''
else:
msgBody = req.body
self.ui.outputWindow.append(
'{}\n{}\n{}\n\n{}'.format(
'\n\n----------- 发送请求 -----------',
req.method + ' ' + req.url,
'\n'.join('{}: {}'.format(k, v) for k, v in req.headers.items()),
msgBody,
))
def pretty_print_response(self,res):
self.ui.outputWindow.append(
'{}\nHTTP/1.1 {}\n{}\n\n{}'.format(
'\n\n----------- 得到响应 -----------',
res.status_code,
'\n'.join('{}: {}'.format(k, v) for k, v in res.headers.items()),
res.text,
))
app = QApplication([])
# 加载 icon
app.setWindowIcon(QIcon('logo.png'))
httpClient = HttpClient()
httpClient.ui.show()
app.exec_()