基于PYQT的MQTT协议测试工具
来源:互联网 发布:米卡有软件 编辑:程序博客网 时间:2024/06/07 02:49
这段时间公司有个项目使用到了MQTT的协议与智能硬件终端进行通信,需要对通讯协议进行验证,正好这段时间一直在研究PYQT,正好写个GUI小工具,给测试组的同事们使用
主界面
主界面主要实现Publish和Subscribe 消息订阅和发送,使用了PAHO的mqtt库,我这边主要是实现了一个界面的封装
设置界面
设置界面主要是使用了python自带的sqlite数据库保存用户连接MQTT服务器时的一些个性化参数,用户可以对自己的保存的连接进行个性化命名,选中相应的连接,点击ok即可
整个小工具去掉库文件,自己实现的代码在1000行左右,只是一个初级版本,其中ConfigDialog.py就是设置页面编码,mtest.py是主界面的编码,mqttimage文件是一些图片的集合,对PYQT不是很了解的同学可以去查阅一下相关资料。
上代码
ConfigDialog.py
from PyQt4 import QtCore, QtGuiimport random, mqttimageimport sqlite3, sys, os# from PyQt4.QtGui import * # from PyQt4.QtCore import * from PyQt4.Qt import QMessageBox, QRegExpValidatorQtCore.QTextCodec.setCodecForTr(QtCore.QTextCodec.codecForName("utf8"))childlist=[] user=''class ConfigDialog(QtGui.QDialog): def __init__(self, parent=None): super(ConfigDialog, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Window) #设置最大化最小化按钮 self.setWindowTitle(self.tr("设置")) self.resize(800,450) QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks'))#设置整体风格 QtGui.QApplication.setPalette(QtGui.QApplication.style().standardPalette())#设置整体风格 mainSplitter = QtGui.QSplitter(QtCore.Qt.Horizontal,self) amendPushButton = QtGui.QPushButton(self.tr("OK")) closePushButton = QtGui.QPushButton(self.tr("Cancel")) self.applyPushButton = QtGui.QPushButton(self.tr("Save")) self.applyPushButton.setDisabled(True)# 初始化save不可用 buttonLayout = QtGui.QHBoxLayout() buttonLayout.addStretch(9) buttonLayout.addWidget(self.applyPushButton) buttonLayout.addWidget(amendPushButton)# buttonLayout.addWidget(closePushButton) addButton = QtGui.QPushButton(self.tr("")) addButton.setFlat(True) addButton.setIcon(QtGui.QIcon(":img/image/plus.png")) delButton = QtGui.QPushButton(self.tr("")) delButton.setFlat(True) delButton.setIcon(QtGui.QIcon(":img/image/minus.png")) buttonLayout1 = QtGui.QGridLayout() buttonLayout1.addWidget(addButton,0,0) buttonLayout1.addWidget(delButton,0,2) self.treeWidget = QtGui.QTreeWidget() self.treeWidget.setColumnCount(1)#设置列数1 self.treeWidget.setHeaderLabels([self.tr("Connections")]) self.root= QtGui.QTreeWidgetItem(self.treeWidget) self.root.setText(0,self.tr("Profile")) self.treeWidget.expandAll() #节点全部展开 treeLayout = QtGui.QVBoxLayout() treeLayout.addWidget(self.treeWidget) treeLayout.addLayout(buttonLayout1) self.Param1 = Param() rightQSplitter = QtGui.QFrame(mainSplitter) stack = QtGui.QStackedWidget() stack.setFrameStyle(QtGui.QFrame.Panel|QtGui.QFrame.Raised) stack.addWidget(self.Param1) mainLayout_1 = QtGui.QHBoxLayout() mainLayout_1.addLayout(treeLayout) mainLayout_1.addWidget(stack) mainLayout = QtGui.QVBoxLayout(rightQSplitter) mainLayout.setMargin(1) mainLayout.setSpacing(6) mainLayout.addLayout(mainLayout_1) Layout = QtGui.QVBoxLayout() Layout.addWidget(mainSplitter) Layout.addLayout(buttonLayout) self.setLayout(Layout) self.initDB()#初始化数据库 '''槽函数''' amendPushButton.clicked.connect(self.accept) closePushButton.clicked.connect(self.reject) self.applyPushButton.clicked.connect(self.apply) addButton.clicked.connect(self.add) delButton.clicked.connect(self.delete) self.connect(self.treeWidget, QtCore.SIGNAL("itemClicked(QTreeWidgetItem*,int)"),self.data_query) '''''' def getsetdata(self): self.ProfileName = self.Param1.nameEdit.text() self.Host = self.Param1.HostEdit.text() self.portValue = self.Param1.portSpinbox.value() self.keepValue = self.Param1.keepaliveSpinbox.value() self.client = self.Param1.ClientEdit.text() self.user = self.Param1.tab.gen.UserEdit.text() self.password = self.Param1.tab.gen.PassWordEdit.text() self.visionValue = self.Param1.tab.gen.visionComboBox.currentText() self.cleanssionValue = self.Param1.tab.gen.CleanSessionComboBox.currentText() if self.cleanssionValue =='True': self.cleanssion = True# print self.cleanssion else: self.cleanssion = False# print self.cleanssion self.napsBooL = self.Param1.tab.gen.groupBox.isChecked()#namepassword 框是否勾选 self.pascheck = self.Param1.tab.gen.checkBox1.checkState() return self.ProfileName, self.Host, self.portValue, self.keepValue, self.client, self.user, self.password, self.visionValue, self.cleanssion, self.napsBooL, self.pascheck def data_query(self, QTreeWidgetItem, int): global rot parent = QTreeWidgetItem.parent() if parent == -1: return 1 elif parent == None: self.Param1.nameEdit.setText('') self.Param1.HostEdit.setText('') self.Param1.portSpinbox.setValue(0) self.Param1.keepaliveSpinbox.setValue(0) self.Param1.ClientEdit.setText('') self.Param1.tab.gen.UserEdit.setText('') self.Param1.tab.gen.PassWordEdit.setText('') self.applyPushButton.setDisabled(True) else: try: rot = parent.indexOfChild(QTreeWidgetItem) self.applyPushButton.setDisabled(False) except AttributeError: pass cur = self.conn.cursor() cur.execute('SELECT * FROM MQ') self.MQData = cur.fetchall() cur.execute('SELECT * FROM MQ1') self.MQData1 = cur.fetchall() cur.close() self.idname = childlist[rot].text(0) # print childlist[rot].text(0) self.index = len(self.MQData) self.index1 = len(self.MQData1) if self.index > 0 : for x in range(self.index): if self.MQData[x][0] == self.idname: self.Param1.nameEdit.setText(self.idname) self.Param1.HostEdit.setText(self.MQData[x][1]) self.Param1.portSpinbox.setValue(self.MQData[x][2]) self.Param1.keepaliveSpinbox.setValue(self.MQData[x][3]) self.Param1.ClientEdit.setText(self.MQData[x][4]) self.Param1.tab.gen.UserEdit.setText(self.MQData[x][5]) self.Param1.tab.gen.PassWordEdit.setText(self.MQData[x][6]) if self.MQData[x][7] == 'True': self.Param1.tab.gen.CleanSessionComboBox.setCurrentIndex(0) else: self.Param1.tab.gen.CleanSessionComboBox.setCurrentIndex(1) if self.MQData[x][8] == 'V3.1': self.Param1.tab.gen.visionComboBox.setCurrentIndex(0) else: self.Param1.tab.gen.visionComboBox.setCurrentIndex(1) if self.MQData[x][9] == True: self.Param1.tab.gen.groupBox.setChecked(True) else: self.Param1.tab.gen.groupBox.setChecked(False) if self.index1 > 0 : for x in range(self.index1): if self.MQData1[x][0] == self.idname: if self.MQData1[x][1] == 2: self.Param1.tab.gen.checkBox1.setChecked(True) else: self.Param1.tab.gen.checkBox1.setChecked(False) self.Param1.tab.tls.openFileNameLabel.setText(self.MQData1[x][2])# print type(rot)# print rot @staticmethod def data(parent = None): dialog = ConfigDialog(parent) result = dialog.exec_() data = dialog.x() return (data, result == ConfigDialog.Accepted) def apply(self): self.name = self.Param1.nameEdit.text() self.host = self.Param1.HostEdit.text() self.portValue = self.Param1.portSpinbox.value() self.keepValue = self.Param1.keepaliveSpinbox.value() self.client = self.Param1.ClientEdit.text() self.user = self.Param1.tab.gen.UserEdit.text() self.password = self.Param1.tab.gen.PassWordEdit.text() self.visionValue = self.Param1.tab.gen.visionComboBox.currentText() self.cleanssionValue = self.Param1.tab.gen.CleanSessionComboBox.currentText() self.napsBooL = self.Param1.tab.gen.groupBox.isChecked()#namepassword 框是否勾选 self.pascheck = self.Param1.tab.gen.checkBox1.checkState() self.file = self.Param1.tab.tls.openFileNameLabel.text() print self.file# print self.pascheck# print self.napsBooL if self.cleanssionValue =='True': self.cleanssion = True# print self.cleanssion else: self.cleanssion = False# print self.cleanssion count = len(childlist) for x in range(count): if rot == x : childlist[rot].setText(0,self.tr(self.name))# print self.idname c = self.conn.cursor() c.execute('''UPDATE MQ SET CONNAME = '%s' ,HOSTNAME = '%s', PORT = %d, KEEPLIVE = %d, CLIENTID = '%s', USERNAME = '%s', PASSWORD = '%s', CLEANSSID = '%s', MQVISION = '%s', NAPSBOOL = %d\ where CONNAME = '%s' ''' %(self.name, self.host, self.portValue, self.keepValue, self.client, self.user, self.password, self.cleanssionValue, self.visionValue, self.napsBooL, self.idname)) c.execute('''UPDATE MQ1 SET CONNAME = '%s' ,PASCHECK = %d, FILE = '%s'\ where CONNAME = '%s' ''' %(self.name, self.pascheck, self.file, self.idname)) self.conn.commit() QMessageBox.information(self, self.tr("提示"), self.tr("保存成功")) def add(self): self.name = self.Param1.nameEdit.text() self.host = self.Param1.HostEdit.text() self.portValue = self.Param1.portSpinbox.value() self.keepValue = self.Param1.keepaliveSpinbox.value() self.client = self.Param1.ClientEdit.text() self.user = self.Param1.tab.gen.UserEdit.text() self.password = self.Param1.tab.gen.PassWordEdit.text() self.visionValue = self.Param1.tab.gen.visionComboBox.currentText() self.cleanssionValue = self.Param1.tab.gen.CleanSessionComboBox.currentText() self.napsBooL = self.Param1.tab.gen.groupBox.isChecked() self.pascheck = self.Param1.tab.gen.checkBox1.checkState() self.file = self.Param1.tab.tls.openFileNameLabel.text() print self.file self.index += 1 self.child = QtGui.QTreeWidgetItem(self.root) randomID = "connect_"+"".join(random.choice("0123456789ADCDEF") for x in range(15-5)) self.child.setText(0,self.tr(randomID)) childlist.append(self.child) self.conn.execute("INSERT INTO MQ VALUES ('%s','%s', %d, %d,'%s','%s','%s','%s','%s', %d)"%(randomID, self.host, self.portValue, self.keepValue,\ self.client, self.user, self.password, self.cleanssionValue, self.visionValue, self.napsBooL)) self.conn.execute("INSERT INTO MQ1 VALUES ('%s', %d, '%s')"%(randomID, self.pascheck, self.file)) def delete(self): count = len(childlist) for x in range(count): if rot == x : self.root.removeChild(childlist[rot]) childlist.remove(childlist[rot]) self.conn.execute("DELETE FROM MQ WHERE CONNAME = '%s' " % (self.idname)) self.conn.execute("DELETE FROM MQ1 WHERE CONNAME = '%s' " % (self.idname)) def initDB(self): if os.path.exists('MQ.db'): self.conn = sqlite3.connect('MQ.db') self.conn.isolation_level = None else: self.conn = sqlite3.connect('MQ.db') self.conn.isolation_level = None self.conn.execute('''CREATE TABLE MQ (CONNAME char PRIMARY KEY NOT NULL, HOSTNAME char(255), PORT INT, KEEPLIVE INT, CLIENTID char(255), USERNAME char(255), PASSWORD char(255), CLEANSSID BOOLEAN, MQVISION char(255), NAPSBOOL BOOLEAN)''') self.conn.execute('''CREATE TABLE MQ1 (CONNAME char PRIMARY KEY NOT NULL, PASCHECK INT, FILE char(255))''') self.cur = self.conn.cursor() self.cur.execute('SELECT * FROM MQ') self.MQData = self.cur.fetchall() self.cur.execute('SELECT * FROM MQ1') self.MQData1 = self.cur.fetchall() self.cur.close() self.index = len(self.MQData) if self.index > 0 : for x in range(self.index): self.child = QtGui.QTreeWidgetItem(self.root)# print self.child childlist.append(self.child) id = self.MQData[x][0] self.child.setText(0,self.tr(id))class Param(QtGui.QDialog): def __init__(self, parent=None): super(Param, self).__init__(parent)# self.resize(800,400) nameGroup = QtGui.QGroupBox("Name Profile") nameLabel = QtGui.QLabel("Connect Name:") self.nameEdit = QtGui.QLineEdit() '''只允许输入字母和数字''' re1=QtCore.QRegExp("[a-zA-Z0-9]+$") self.nameEdit.setValidator(QtGui.QRegExpValidator(re1,self)) '''''' ClientGroup = QtGui.QGroupBox("CLient Profile") Hostlabel = QtGui.QLabel("HostName:") self.HostEdit = QtGui.QLineEdit() Portlabel = QtGui.QLabel("Port:") ClientIdlabel = QtGui.QLabel("ClientId:") self.ClientEdit = QtGui.QLineEdit() Keepalivelabel = QtGui.QLabel("Keepalive:") checkBox1 = QtGui.QCheckBox("clean_session") Button1 = QtGui.QPushButton("Generate") amendPushButton = QtGui.QPushButton(self.tr("Apply")) closePushButton = QtGui.QPushButton(self.tr("关闭")) buttonLayout = QtGui.QHBoxLayout() buttonLayout.addStretch(0)# buttonLayout.addWidget(amendPushButton)# buttonLayout.addWidget(closePushButton) self.portSpinbox = QtGui.QSpinBox() self.portSpinbox.setMaximum(9999) self.portSpinbox.setMinimum(0)# self.portSpinbox.setValue(1883) self.keepaliveSpinbox = QtGui.QSpinBox() self.keepaliveSpinbox.setMaximum(9999) self.keepaliveSpinbox.setMinimum(0)# self.keepaliveSpinbox.setValue(60) nameLayout = QtGui.QGridLayout() nameLayout.addWidget(nameLabel, 0, 0) nameLayout.addWidget(self.nameEdit, 0, 1) nameGroup.setLayout(nameLayout) inputMaskLabel = QtGui.QLabel("MQTT") self.inputMaskComboBox = QtGui.QComboBox() self.inputMaskComboBox.addItem("V3.1") self.inputMaskComboBox.addItem("V3.1.1") inputMaskLabel1 = QtGui.QLabel("Clean_session") self.inputMaskComboBox1 = QtGui.QComboBox() self.inputMaskComboBox1.addItem("True") self.inputMaskComboBox1.addItem("False") '''槽函数''' Button1.clicked.connect(self.gengrate) '''''' clientLayout = QtGui.QGridLayout() clientLayout.addWidget(Hostlabel, 0, 0) clientLayout.addWidget(self.HostEdit, 0, 1) clientLayout.addWidget(Portlabel, 0,2) clientLayout.addWidget(self.portSpinbox, 0,3) clientLayout.addWidget(Keepalivelabel, 1, 0) clientLayout.addWidget(self.keepaliveSpinbox, 1, 1, 1, 3) clientLayout.addWidget(ClientIdlabel, 2,0) clientLayout.addWidget(self.ClientEdit, 2, 1, 1, 2) clientLayout.addWidget(Button1,2,3) ClientGroup.setLayout(clientLayout) self.tab=TabDialog() mainLayout = QtGui.QVBoxLayout() mainLayout.addWidget(nameGroup) mainLayout.addWidget(ClientGroup) mainLayout.addWidget(self.tab) mainLayout.addLayout(buttonLayout) mainLayout.addSpacing(2) mainLayout.addStretch() self.setLayout(mainLayout) def gengrate(self): gen = "Admin_" + "".join(random.choice("0123456789ADCDEF") for x in range(23-5)) self.ClientEdit.setText(gen)class TabDialog(QtGui.QWidget): def __init__(self, parent=None): super(TabDialog, self).__init__(parent) tabWidget = QtGui.QTabWidget() self.gen=GeneralTab() self.tls=TLSTab() tabWidget.addTab(self.gen, "General") tabWidget.addTab(self.tls, "TLS") mainLayout = QtGui.QVBoxLayout() mainLayout.addWidget(tabWidget) self.setLayout(mainLayout) class GeneralTab(QtGui.QWidget): def __init__(self, parent=None): super(GeneralTab, self).__init__(parent)# clean_session_checkBox = QtGui.QCheckBox("clean_session") groupBox = QtGui.QGroupBox("UserName && PassWord") visionLabel = QtGui.QLabel("MQTT vision:") self.visionComboBox = QtGui.QComboBox() self.visionComboBox.addItem("V3.1") self.visionComboBox.addItem("V3.1.1") CleanSessionLabel = QtGui.QLabel("Clean session:") self.CleanSessionComboBox = QtGui.QComboBox() self.CleanSessionComboBox.addItem("True") self.CleanSessionComboBox.addItem("False") VersionLayout = QtGui.QGridLayout() VersionLayout.addWidget(CleanSessionLabel,0,0) VersionLayout.addWidget(self.CleanSessionComboBox,0,1) VersionLayout.addWidget(visionLabel,1,0) VersionLayout.addWidget(self.visionComboBox,1,1) grid = QtGui.QGridLayout() grid.addWidget(self.createuserGroup(), 0, 0) grid.addLayout(VersionLayout, 1, 0) grid.setColumnStretch(1,0) self.setLayout(grid) '''槽函数''' '''''' def createuserGroup(self): self.groupBox = QtGui.QGroupBox("UserName && PassWord") self.groupBox.setCheckable(True) self.groupBox.setChecked(True) UserLabel = QtGui.QLabel("UserName:") self.UserEdit = QtGui.QLineEdit()# self.UserEdit.setText('liuxh') PassWordLabel = QtGui.QLabel("PassWord:") self.PassWordEdit = QtGui.QLineEdit()# self.PassWordEdit.setText('123456') self.checkBox1 = QtGui.QCheckBox("")# self.checkBox1.setCheckState(True) '''槽函数''' self.checkBox1.stateChanged.connect(self.hide) '''''' self.checkBox1.setChecked(True) NamePassLayout = QtGui.QGridLayout() NamePassLayout.addWidget(UserLabel,0,0) NamePassLayout.addWidget(self.UserEdit,0,1) NamePassLayout.addWidget(PassWordLabel,1,0) NamePassLayout.addWidget(self.PassWordEdit,1,1) NamePassLayout.addWidget(self.checkBox1,1,2) vbox = QtGui.QVBoxLayout() vbox.addLayout(NamePassLayout) vbox.addStretch() self.groupBox.setLayout(vbox) return self.groupBox def hide(self):# print self.checkBox1.checkState() if self.checkBox1.checkState() == 2: self.PassWordEdit.setEchoMode(QtGui.QLineEdit.Password) else: self.PassWordEdit.setEchoMode(QtGui.QLineEdit.Normal)class TLSTab(QtGui.QDialog): def __init__(self, parent=None): super(TLSTab, self).__init__(parent) frameStyle = QtGui.QFrame.Sunken | QtGui.QFrame.Panel groupBox = QtGui.QGroupBox("CA certificate") self.openFileNameLabel = QtGui.QLabel() self.openFileNameButton = QtGui.QPushButton("open") self.openFileNameLabel.setFrameStyle(frameStyle) self.openFileNameLabel.setStyleSheet("background:white") TLSLayout = QtGui.QGridLayout() TLSLayout.addWidget(self.openFileNameLabel,0,0,1,5) TLSLayout.addWidget(self.openFileNameButton,0,6,1,1) groupBox.setLayout(TLSLayout) SSLLayout1 = QtGui.QGridLayout() SSLLayout1.addWidget(groupBox,0,0) self.setLayout(SSLLayout1) self.openFileNameButton.clicked.connect(self.setOpenFileName1) def setOpenFileName1(self): options = QtGui.QFileDialog.Options() fileName = QtGui.QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", self.openFileNameLabel.text(), "All Files (*);;Text Files (*.txt)") if fileName: self.openFileNameLabel.setText(fileName)
mtest.py
from PyQt4 import QtCore, QtGuiimport sys, socket, binasciiimport mqttimage,timeimport paho.mqtt.publish as publishimport paho.mqtt.client as mqttfrom ConfigDialog import *import ctypes QtCore.QTextCodec.setCodecForTr(QtCore.QTextCodec.codecForName("utf8"))ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("myappid") #状态栏单独显示class MainWindow(QtGui.QMainWindow): def __init__(self,parent=None): super(MainWindow,self).__init__(parent) self.setWindowTitle(self.tr("MQ TEST")) self.setWindowIcon(QtGui.QIcon(":img/image/mq.png")); QtCore.QThread.sleep(0)#启动画面停留时间 QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('Cleanlooks'))#设置整体风格 QtGui.QApplication.setPalette(QtGui.QApplication.style().standardPalette())#设置整体风格 self.resize(800,550)#####设置窗口大小# self.statusBar().showMessage(self.tr("未建立连接"))# self.StackDialog=StackDialog() # 开始装载样式表# qss_file = open('style.qss').read()# self.setStyleSheet(qss_file) self.a = MQ() self.setCentralWidget(self.a) self.createActions() self.createMenus() self.createToolBars() def createActions(self):# self.fileOpenAction=QtGui.QAction(QtGui.QIcon(":pic/image/xitong/folder_blue.png"),self.tr("打开"),self)# self.fileOpenAction.setShortcut("Ctrl+O")# self.fileOpenAction.setStatusTip(self.tr("打开一个文件"))# self.connect(self.fileOpenAction,QtCore.SIGNAL("triggered()"),self.slotOpenFile) self.fileSaveAction=QtGui.QAction(QtGui.QIcon(":pic/image/xitong/save.png"),self.tr("保存"),self) self.fileSaveAction.setShortcut("Ctrl+S") self.fileSaveAction.setStatusTip(self.tr("保存文件")) self.connect(self.fileSaveAction,QtCore.SIGNAL("triggered()"),self.fileSaveAs) self.settingAction=QtGui.QAction(QtGui.QIcon(":img/image/setting.png"),self.tr("设置"),self) self.settingAction.setShortcut("Ctrl+H") self.settingAction.setStatusTip(self.tr("设置")) self.settingAction.triggered.connect(self.a.osd) self.aboutAction=QtGui.QAction(QtGui.QIcon(":img/image/mq.png"),self.tr("关于"),self) self.aboutAction.setShortcut("Ctrl+j") self.aboutAction.triggered.connect(self.about) self.actionQuit = QtGui.QAction(self.tr("退出"), self, shortcut=QtGui.QKeySequence.Quit) self.actionQuit.triggered.connect(self.close) def createMenus(self): fileMenu = self.menuBar().addMenu(self.tr("文件"))# fileMenu.addAction(self.fileOpenAction)# fileMenu.addAction(self.fileSaveAction) fileMenu.addAction(self.settingAction) fileMenu.addAction(self.actionQuit) helpMenu = self.menuBar().addMenu(self.tr("帮助")) helpMenu.addAction(self.aboutAction) def createToolBars(self): fileToolBar=self.addToolBar("File")# fileToolBar.addAction(self.fileOpenAction)# fileToolBar.addAction(self.fileSaveAction) fileToolBar.addAction(self.settingAction) def slotOpenFile(self): fileName=QtGui.QFileDialog.getOpenFileName(self) if fileName.isEmpty()==False: if self.text.document().isEmpty(): self.loadFile(fileName) else: newWin=MainWindow() newWin.show() newWin.loadFile(fileName) def slotSaveFile(self): pass def fileSave(self): printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution) printer.setOutputFormat(QtGui.QPrinter.PdfFormat) browser.document().print_(printer) def fileSaveAs(self): printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution) dlg = QtGui.QPrintDialog(printer, self)# if self.textEdit.textCursor().hasSelection():# dlg.addEnabledOption(QtGui.QAbstractPrintDialog.PrintSelection) dlg.setWindowTitle("Print Document") if dlg.exec_() == QtGui.QDialog.Accepted: browser.print_(printer) del dlg def about(self): QtGui.QMessageBox.about(self, "About", "author:liuxiaohu\n" "vision:V1.0.0\n" "by Python 2.7 && PyQt4") class MQ(QtGui.QWidget): def __init__(self, parent=None): super(MQ, self).__init__(parent) nameLabel = QtGui.QLabel() nameLabel.setPixmap(QtGui.QPixmap(":img/image/note.png")) frameStyle = QtGui.QFrame.Sunken | QtGui.QFrame.Panel self.nameEdit = QtGui.QLineEdit() self.nameEdit.setStyleSheet(" height:20px;width: 60px;background:white") self.nameEdit.setEnabled(False) global dataflag#数据刷新标志 self.ConnectButton = QtGui.QPushButton(self.tr("连接"))# self.ConnectButton.setStyleSheet(" width: 60px;") self.ConnectButton.setIcon(QtGui.QIcon(":img/image/tuxiang/connected.png")) self.DisConnectButton = QtGui.QPushButton(self.tr("断开")) self.DisConnectButton.setDisabled(True)# self.DisConnectButton.setStyleSheet(" width: 60px;") self.DisConnectButton.setIcon(QtGui.QIcon(":img/image/tuxiang/disconnected.png")) self.SettingButton = QtGui.QPushButton() self.SettingButton.setIcon(QtGui.QIcon(":img/image/disconnect.png")) self.SettingButton.setFlat(True) '''槽函数''' # self.SettingButton.clicked.connect(self.osd) self.ConnectButton.clicked.connect(self.conne) self.DisConnectButton.clicked.connect(self.disconne) ''''''# self.PubLabel = QtGui.QLabel("Retained") self.portSpinbox = QtGui.QSpinBox() self.portSpinbox.setMaximum(9999) self.portSpinbox.setMinimum(0) self.portSpinbox.setValue(1883) self.keepaliveSpinbox = QtGui.QSpinBox() self.keepaliveSpinbox.setMaximum(9999) self.keepaliveSpinbox.setMinimum(0) self.keepaliveSpinbox.setValue(60) nameLayout = QtGui.QGridLayout() nameLayout.addWidget(nameLabel, 0, 0,) nameLayout.addWidget(self.nameEdit, 0, 1) nameLayout.addWidget(self.SettingButton,0, 2) nameLayout.addWidget(self.ConnectButton, 0, 3) nameLayout.addWidget(self.DisConnectButton, 0, 4) self.tab=TabDialog() mainLayout = QtGui.QVBoxLayout() mainLayout.addLayout(nameLayout) mainLayout.addWidget(self.tab) mainLayout.addSpacing(6)# mainLayout.setMargin(0)# mainLayout.addStretch() self.setLayout(mainLayout) def osd(self): global ProfileName, Host, portValue, keepValue, clientids, user, password, visionValue, cleanssionValue, napsBooL, pascheck dialog=ConfigDialog(self) result = dialog.exec_() for x in range(len(childlist)): childlist.remove(childlist[0]) if result: ProfileName, Host, portValue, keepValue, clientids, user, password, visionValue, cleanssionValue, napsBooL, pascheck = dialog.getsetdata() print ProfileName, Host, portValue, keepValue, clientids, user, password, visionValue, cleanssionValue, napsBooL, pascheck self.nameEdit.setText(ProfileName) dialog.destroy() def on_connect(self, client, obj, flags, rc): print("rc: "+str(rc)) if str(rc) == '0': self.bwThread.updatedicon.emit()#发送信号 def icon(self): self.SettingButton.setIcon(QtGui.QIcon(":img/image/connect.png")) self.ConnectButton.setDisabled(True) pub.setDisabled(False) sub.setDisabled(False) def disconne(self): pub.setDisabled(True) sub.setDisabled(True) client.disconnect() self.bwThread.stop() self.SettingButton.setIcon(QtGui.QIcon(":img/image/disconnect.png")) self.ConnectButton.setDisabled(False)# self.stopTimer() def initTimer(self): self.timer = QtCore.QTimer(self) #初始化一个定时器 self.timer.timeout.connect(self.pingreq) #计时结束调用operate()方法 self.timer.start((keepValue-1)*1000) #设置计时间隔并启动 def stopTimer(self): self.timer.stop() def conne(self): try: if visionValue == QtCore.QString('V3.1.1'): self.mqttvision = mqtt.MQTTv311 else: self.mqttvision = mqtt.MQTTv31 hostname = unicode(QtCore.QString(Host).toUtf8(),'utf8','ignore') clientid = unicode(QtCore.QString(clientids).toUtf8(),'utf8','ignore') self.username = unicode(QtCore.QString(user).toUtf8(),'utf8','ignore') self.pswd = unicode(QtCore.QString(password).toUtf8(),'utf8','ignore')# print type(hostname) self.DisConnectButton.setDisabled(False) global client client = mqtt.Client(client_id=clientid, clean_session=cleanssionValue, userdata=None, protocol=self.mqttvision) client.on_publish = self.on_publish client.on_connect = self.on_connect client.on_message = self.on_message client.on_subscribe = self.on_subscribe if napsBooL == True: self.setAutho() #设置用户名和密码 try: client.connect(hostname, keepalive = keepValue) #向服务器发起连接# self.initTimer() self.bwThread = WorkThread() self.bwThread.updated.connect(self.append) self.bwThread.updatedicon.connect(self.icon) rc = self.bwThread.start() return rc except socket.error: QMessageBox.information(self, self.tr("提示"), self.tr("服务器地址不存在,请重新输入")) except ValueError: QMessageBox.critical(self, self.tr("提示"), self.tr("请输入正确服务器地址")) except NameError: QMessageBox.information(self, self.tr("提示"), self.tr("请在设置页面选择相应的配置文件")) def pingreq(self): client.send_pingreq() def on_message(self, mqttc, obj, msg): global a,b,c a = msg.topic b = msg.qos c = msg.payload self.bwThread.updated.emit()#发送信号# print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)) def strformathex(self, str): self.index=0 self.a=list() self.b=list(str) self.len = len(str)/2 for i in range(self.len): self.a.append(self.b[self.index]+self.b[self.index+1]) self.a.append(" ") self.index=self.index+2 return ''.join(self.a) def append(self): browser.append(a+" "+str(b)+" "+str(c)) m = binascii.b2a_hex(c) h = self.strformathex(m) h.rstrip() t = time.asctime( time.localtime(time.time()) ) browser.append(a+" "+str(b)+" "+ h + " "+t) def on_publish(self, mqttc, obj, mid): print("message mid is: "+str(mid)) def on_subscribe(self, mqttc, obj, mid, granted_qos): print("Subscribed: "+str(mid)+" "+str(granted_qos)) def on_log(self, mqttc, obj, level, string): print(string) def setAutho(self): client.username_pw_set(self.username, self.pswd) class WorkThread(QtCore.QThread): updated = QtCore.pyqtSignal()#自定义信号,更新数据 updatedicon = QtCore.pyqtSignal()#自定义信号,更新图标 def __init__(self, parent=None): super(WorkThread, self).__init__(parent) self.flag = 1 def run(self): while True: if self.flag == 1: client.loop() else: break def stop(self): print 'setting flag false' self.flag = 0 print self.flag class TabDialog(QtGui.QWidget): def __init__(self, parent=None): super(TabDialog, self).__init__(parent)# self.setGeometry(300,30,30,30)# self.show() tabWidget = QtGui.QTabWidget() style = "QTabWidget::pane{border:none;\ QTabWidget::tab-bar{alignment:left;}}\ QTabBar::tab{background:#FFF5EE;color:black;min-width:30ex;min-height:10ex;}\ QTabBar::tab:hover{background:rgb(255, 255, 255, 255);}\ QTabBar::tab:selected{border-color:white;background:#00BFFF;color:white;}" tabWidget.setStyleSheet(style) global pub, sub pub=PublishTab() sub=SubTab() pub.setDisabled(True) sub.setDisabled(True) tabWidget.addTab(pub, "Publish") tabWidget.addTab(sub, "Subcribe") mainLayout = QtGui.QGridLayout() mainLayout.addWidget(tabWidget,5,1) mainLayout.setMargin(1) mainLayout.setSpacing(6) self.setLayout(mainLayout) class PublishTab(QtGui.QWidget): def __init__(self, parent=None): super(PublishTab, self).__init__(parent) publishGroup = QtGui.QGroupBox("Publish Message") self.PubLabel = QtGui.QLabel("PubTopic:") self.Playload = QtGui.QLabel("Message :") self.pubEdit = QtGui.QLineEdit() self.PlayloadEdit = QtGui.QLineEdit() self.PlayloadEdit.setStyleSheet(" height: 37px;") self.PushButton = QtGui.QPushButton(self.tr("Publish")) self.PushButton.setStyleSheet(" height: 50px;background:#D3D3D3") global pubbrowser pubbrowser = QtGui.QTextBrowser() pubbrowser.setFrameStyle(QtGui.QFrame.Panel|QtGui.QFrame.Sunken)# style = "color: rgb(127, 0, 63);\# background-image: url(:img/image/3.jpg);" style = "color:#7CFC00;background:#4D4D4D" pubbrowser.setStyleSheet(style) self.QosLabel = QtGui.QLabel("Qos") self.QosComboBox = QtGui.QComboBox() self.QosComboBox.addItem("0") self.QosComboBox.addItem("1") self.QosComboBox.addItem("2") self.formatLabel = QtGui.QLabel("Send Format") self.formatComboBox = QtGui.QComboBox() self.formatComboBox.addItem("HEX") self.formatComboBox.addItem("Plain") self.Retained = QtGui.QCheckBox("Retained") self.pubLayout = QtGui.QGridLayout() self.pubLayout.addWidget(self.PubLabel,0,0) self.pubLayout.addWidget(self.pubEdit,0,1) self.pubLayout.addWidget(self.QosLabel,0,2) self.pubLayout.addWidget(self.QosComboBox,0,3) self.pubLayout.addWidget(self.Retained,0,4) self.pubLayout.addWidget(self.Playload,1,0) self.pubLayout.addWidget(self.PlayloadEdit,1,1) self.pubLayout.addWidget(self.formatLabel,1,2) self.pubLayout.addWidget(self.formatComboBox,1,3,1,2) self.pubLayout.setSpacing(10) self.Vlineframe = QtGui.QFrame() self.Vlineframe.setFrameStyle(QtGui.QFrame.VLine|QtGui.QFrame.Sunken) saveButton = QtGui.QPushButton(self.tr("保存")) saveButton.setFlat(True) saveButton.setIcon(QtGui.QIcon(":img/image/pdf.png")) delButton = QtGui.QPushButton(self.tr("清空")) delButton.setFlat(True) delButton.setIcon(QtGui.QIcon(":img/image/recycle.png")) self.buttonLayout1 = QtGui.QGridLayout() self.buttonLayout1.addWidget(saveButton,0,0) self.buttonLayout1.addWidget(delButton,0,2) '''槽函数''' self.PushButton.clicked.connect(self.push) saveButton.clicked.connect(self.save) delButton.clicked.connect(self.clear) '''''' clientLayout = QtGui.QGridLayout() clientLayout.addLayout(self.pubLayout, 0, 0) clientLayout.addWidget(self.Vlineframe, 0, 1) clientLayout.addWidget(self.PushButton, 0, 2) publishGroup.setLayout(clientLayout) mainLayout = QtGui.QVBoxLayout() mainLayout.addWidget(publishGroup) mainLayout.addWidget(pubbrowser) mainLayout.addLayout(self.buttonLayout1) mainLayout.addSpacing(2) self.setLayout(mainLayout) def push(self): x = time.asctime( time.localtime(time.time()) ) self.pubtopic = self.pubEdit.text() self.pubtopic = unicode(QtCore.QString(self.pubtopic).toUtf8(),'utf8','ignore') self.pubmessage = self.PlayloadEdit.text() self.pubmessage = unicode(self.pubmessage) pubbrowser.append('[Pubtopic]:---' + self.pubtopic + '---[' + x + ']') pubbrowser.append('[Message]:---' + self.pubmessage + '---[' + x + ']') if self.formatComboBox.currentIndex() == 0: # self.pubmessage = unicode(self.pubmessage) self.pubmessage = bytearray().fromhex(self.pubmessage) if self.QosComboBox.currentText() == QtCore.QString('0'): self.qos = 0 elif self.QosComboBox.currentText() == QtCore.QString('1'): self.qos = 1 if self.QosComboBox.currentText() == QtCore.QString('2'): self.qos = 2 self.Retain = self.Retained.checkState() # print self.pubtopic, self.pubmessage, self.qos, self.Retain client.publish(self.pubtopic, self.pubmessage) def save(self): printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution) dlg = QtGui.QPrintDialog(printer, self) dlg.setWindowTitle("Print Document") if dlg.exec_() == QtGui.QDialog.Accepted: pubbrowser.print_(printer) del dlg def clear(self): pubbrowser.clear() class SubTab(QtGui.QWidget): def __init__(self, parent=None): super(SubTab, self).__init__(parent) SublishGroup = QtGui.QGroupBox("Subscribe") self.SubLabel = QtGui.QLabel("SubTopic:") self.SubEdit = QtGui.QLineEdit() self.SubEdit.setText('$SYS/broker/bytes/received') self.SubButton = QtGui.QPushButton(self.tr("Subscribe")) self.SubButton.setStyleSheet(" height: 50px;background:#D3D3D3") global browser browser = QtGui.QTextBrowser() browser.setFrameStyle(QtGui.QFrame.Panel|QtGui.QFrame.Sunken) browser.ensureCursorVisible()#滚动条自动# style = "color: rgb(127, 0, 63);\# background-image: url(:img/image/3.jpg);" style = "color:#ffffff;background:#000000" browser.setStyleSheet(style) self.QosLabel = QtGui.QLabel("Qos") self.QosComboBox = QtGui.QComboBox() self.QosComboBox.addItem("0") self.QosComboBox.addItem("1") self.QosComboBox.addItem("2") self.pubLayout = QtGui.QGridLayout() self.pubLayout.addWidget(self.SubLabel,0,0) self.pubLayout.addWidget(self.SubEdit,0,1) self.pubLayout.addWidget(self.QosLabel,0,2) self.pubLayout.addWidget(self.QosComboBox,0,3) self.pubLayout.setSpacing(10) self.Vlineframe = QtGui.QFrame() self.Vlineframe.setFrameStyle(QtGui.QFrame.VLine|QtGui.QFrame.Sunken) saveButton = QtGui.QPushButton(self.tr("保存")) saveButton.setFlat(True) saveButton.setIcon(QtGui.QIcon(":img/image/pdf.png")) delButton = QtGui.QPushButton(self.tr("清空")) delButton.setFlat(True) delButton.setIcon(QtGui.QIcon(":img/image/recycle.png")) self.buttonLayout1 = QtGui.QGridLayout() self.buttonLayout1.addWidget(saveButton,0,0) self.buttonLayout1.addWidget(delButton,0,2) '''槽函数''' self.SubButton.clicked.connect(self.sub) saveButton.clicked.connect(self.save) delButton.clicked.connect(self.clear) '''''' clientLayout = QtGui.QGridLayout() clientLayout.addLayout(self.pubLayout, 0, 0) clientLayout.addWidget(self.Vlineframe, 0, 1) clientLayout.addWidget(self.SubButton, 0, 2)# clientLayout.addWidget(self.browser, 1, 0, 1, 3)# self.pubLayout.setSpacing(2) SublishGroup.setLayout(clientLayout) mainLayout = QtGui.QVBoxLayout() mainLayout.addWidget(SublishGroup) mainLayout.addWidget(browser) mainLayout.addLayout(self.buttonLayout1) mainLayout.addSpacing(2) self.setLayout(mainLayout) def sub(self): x = time.asctime( time.localtime(time.time()) ) self.subtopic = self.SubEdit.text() self.subtopic = str(self.subtopic)#类型转换很重要 browser.append('[Subtopic]:---' + self.subtopic +'---[' + x + ']') if self.QosComboBox.currentText() == QtCore.QString('0'): self.qos = 0 elif self.QosComboBox.currentText() == QtCore.QString('1'): self.qos = 1 if self.QosComboBox.currentText() == QtCore.QString('2'): self.qos = 2 client.subscribe(self.subtopic,self.qos) def save(self): printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution) dlg = QtGui.QPrintDialog(printer, self) dlg.setWindowTitle("Print Document") if dlg.exec_() == QtGui.QDialog.Accepted: browser.print_(printer) del dlg def clear(self): browser.clear() if __name__ == '__main__': app = QtGui.QApplication(sys.argv) splash = QtGui.QSplashScreen(QtGui.QPixmap(":img/image/mqtt.GIF")) splash.show() app.processEvents() mainWin = MainWindow() mainWin.show() splash.finish(mainWin) sys.exit(app.exec_())
附上地址:github
目前只是一个手工测试工具,还不能实现自动测试,对PYQT感兴趣的同学可以互相探讨一下
阅读全文
0 0
- 基于PYQT的MQTT协议测试工具
- 基于MQTT协议的安卓实现
- PHP+ANDROID做消息推送:基于IBM的MQTT协议的Tokudu项目测试
- PHP+ANDROID做消息推送:基于IBM的MQTT协议的Tokudu项目测试
- 基于Jmeter的MQTT测试插件-上
- MQTT 测试工具
- MQTT测试工具推荐
- Android推送通知的实现--PHP+ANDROID做消息推送:基于IBM的MQTT协议的Tokudu项目测试
- MQTT协议说明及测试
- MQTT协议 - Mosquitto安装测试
- Android基于MQTT协议实现的推送功能
- 云巴:基于 MQTT 协议的实时通信编程模型
- Android 基于paho的mqtt service的工具类
- MQTT协议的特点
- MQTT调试工具 mqtt.fx的使用
- 基于MQTT协议推送Android消息
- 基于MQTT协议推送Android消息
- 基于MQTT协议推送Android消息
- 将Bitmap位图转化为base64字符串互转
- WEB前端 -- 单选按钮、下拉、隐藏、表单
- 代码编辑器中文字符编码转换
- Python--json
- Retrofit2.0使用总结
- 基于PYQT的MQTT协议测试工具
- 51nod 与七无关的数
- shell编程快捷方法
- JavaScript 教程
- 数据结构—图论
- 自定义标签
- 探探
- 【数据结构】动态内存管理
- stm32f1/f2/f3/f4/l1的固件库下载