基于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感兴趣的同学可以互相探讨一下

原创粉丝点击