Pyqt4 GUI没有响应,但后台进程仍在运行

时间:2017-06-09 08:50:27

标签: python pyqt python-textfsm

我有一个简单的程序,使用 Netmiko Library 通过SSH连接从交换机/路由器cisco获取信息。

程序效果很好,但程序会冻结,直到过程完成。

我的代码:

当我按下'生成'按钮会在sshConnection运行我的应用程序突然冻结后调用sshConnection功能

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from netmiko import ConnectHandler
from paramiko import SSHException
import jtextfsm as textfsm
import ipaddress
import matplotlib.pyplot as plt
import numpy as np
import io
import time

class Stream(QObject):
    newText = pyqtSignal(str)

    def write(self, text):
        self.newText.emit(str(text))

    def flush(self):
        pass

class MyClass(object):
    def __init__(self, device_type=None, ip=None, username=None, password=None, secret=None, command=None):
        self.device_type = device_type
        self.ip = ip
        self.username = username
        self.password = password
        self.secret = secret
        self.command = command

class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent=parent)
        self.device_list = []  # object array
        self.setWindowTitle("Network Automation")
        self.setFixedSize(350,500)
        ############################# Input IP

        sys.stdout = Stream(newText=self.onUpdateText)

        # Device Type
        lb_device_list = QLabel(self)
        lb_device_list.setText('Device Type')
        self.cb_device_list = QComboBox(self)
        self.cb_device_list.addItem('cisco_ios')
        self.cb_device_list.addItem('cisco_s300')

        # Ip Device
        lb_ip = QLabel(self)
        lb_ip.setText('IP Address')
        self.le_ip = QLineEdit(self)
        self.le_ip.setText('')
        self.le_ip.setPlaceholderText('Input Device IP')
        self.le_ip.setFixedWidth(150)

        # username
        lb_username = QLabel(self)
        self.le_username = QLineEdit(self)
        lb_username.setText('Username')
        self.le_username.setText('')
        self.le_username.setPlaceholderText('Input Username')
        self.le_username.setFixedWidth(150)

        # password
        lb_password = QLabel(self)
        self.le_password = QLineEdit(self)
        lb_password.setText('Password')
        self.le_password.setText('')
        self.le_password.setPlaceholderText('Input Password')
        self.le_password.setFixedWidth(150)

        # Privilage Password
        lb_enable = QLabel(self)
        lb_enable.setText('Privilege Mode Password')
        self.le_enable = QLineEdit(self)
        self.le_enable.setText('')
        self.le_enable.setPlaceholderText('Input Enable Password')
        self.le_enable.setFixedWidth(150)

        # button generate and add
        btgenerate = QPushButton(self)
        btgenerate.setText('Generate')
        btgenerate.setFixedWidth(70)
        btadd = QPushButton(self)
        btadd.setText('Add')

        # button delete
        btdel = QPushButton(self)
        btdel.setFixedWidth(70)
        btdel.setText('Remove')

        # line
        line = QFrame(self)
        line.setFrameShape(QFrame.VLine)
        line.setFrameShadow(QFrame.Sunken)
        line.setLineWidth(3)

        #line 2
        line2 = QFrame(self)
        line2.setFrameShape(QFrame.HLine)
        line2.setFrameShadow(QFrame.Sunken)
        line2.setLineWidth(3)

        ########################### Layout Ip Device List

        lb3 = QLabel(self)
        lb3.setText('IP Device List')
        self.ip_device_list = QListWidget(self)
        self.ip_device_list.setFixedWidth(150)
        # self.combobox_ip_list = QComboBox(self)
        # self.combobox_ip_list.setFixedWidth(170)

        ############################## SubLayout and Layout
        hblayout = QHBoxLayout()
        hblayout.addWidget(btgenerate)
        hblayout.addWidget(btadd)

        ###############################  Processs
        processlabel = QLabel("Process",self)

        self.process = QTextEdit(self)
        self.process.setLineWrapColumnOrWidth(400)
        self.process.setLineWrapMode(QTextEdit.FixedPixelWidth)
        self.process.setReadOnly(True)


        sublayout = QVBoxLayout()
        sublayout.addWidget(lb_device_list)
        sublayout.addWidget(self.cb_device_list)
        sublayout.addWidget(lb_ip)
        sublayout.addWidget(self.le_ip)
        sublayout.addWidget(lb_username)
        sublayout.addWidget(self.le_username)
        sublayout.addWidget(lb_password)
        sublayout.addWidget(self.le_password)
        sublayout.addWidget(lb_enable)
        sublayout.addWidget(self.le_enable)
        sublayout.addLayout(hblayout)

        sublayout2 = QVBoxLayout()
        sublayout2.addWidget(lb3)
        sublayout2.addWidget(self.ip_device_list)
        #sublayout2.addWidget(self.combobox_ip_list)
        sublayout2.addWidget(btdel)
        sublayout2.addStretch(1)

        sublayout3 = QVBoxLayout()
        sublayout3.addWidget(processlabel)
        sublayout3.addWidget(self.process)

        layout = QGridLayout(self)
        layout.addLayout(sublayout, 0, 0)
        layout.addWidget(line, 0, 1)
        layout.addWidget(line2, 1, 0, 1, 3)
        #layout.addWidget(processlabel,2,0)
        layout.addLayout(sublayout3,2,0,2,3)
        layout.addLayout(sublayout2, 0, 2)

        btadd.clicked.connect(self.addDevice)
        btdel.clicked.connect(self.remove)
        btgenerate.clicked.connect(self.sshConection)

    def onUpdateText(self, text):
        cursor = self.process.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.process.setTextCursor(cursor)
        self.process.ensureCursorVisible()

    def __del__(self):
        sys.stdout = sys.__stdout__

    # ----------- AddDevice Process

    def addDevice(self):
        try:
            ip = self.le_ip.text()
            ipaddress.ip_address(ip)
            device_type = str(self.cb_device_list.currentText())
            username = self.le_username.text()
            password = self.le_password.text()
            secret = self.le_enable.text()
            command = 'show tech'
            coomand2 = ''
            self.device_list.append(MyClass(device_type, ip, username, password, secret, command))

            # self.combobox_ip_list.addItem(ip)# Add Ip to ComboBox
            self.ip_device_list.addItem(ip)

            self.le_ip.clear()
            self.le_username.clear()
            self.le_password.clear()
            self.le_enable.clear()
            for list in self.device_list:
                print(list.ip, list.device_type)
        except ValueError:
            print("insert you're ip correctly")
            QMessageBox.question(self, 'Warning', "Insert You're IP Corecctly")

    def remove(self):
        index = self.ip_device_list.currentRow()
        if index != -1:
            self.ip_device_list.takeItem(index)
            del self.device_list[index]

    # ------------- TEXTFSM Process
    def TextFSM(self, nameFile, nameFile2):
        try:
            input_file = open(nameFile + '.txt', encoding='utf-8')  # show version
            raw_text_data = input_file.read()
            input_file.close()

            input_file2 = open(nameFile + '.txt', encoding='utf-8')  # show env
            raw_text_data2 = input_file2.read()
            input_file2.close()

            input_file3 = open(nameFile + '.txt', encoding='utf-8')  # show flash
            raw_text_data3 = input_file3.read()
            input_file3.close()

            input_file4 = open(nameFile + '.txt', encoding='utf-8')  # show memory statistic
            raw_text_data4 = input_file4.read()
            input_file4.close()

            input_file5 = open(nameFile + '.txt', encoding='utf-8')  # show process cpu
            raw_text_data5 = input_file5.read()
            input_file5.close()

            template = open("show-version.textfsm")  # show version
            re_table = textfsm.TextFSM(template)
            fsm_results = re_table.ParseText(raw_text_data)

            template2 = open("show-env.textfsm")  # show env
            re_table2 = textfsm.TextFSM(template2)
            fsm_results2 = re_table2.ParseText(raw_text_data2)

            template3 = open("show-flash.textfsm")  # show flash
            re_table3 = textfsm.TextFSM(template3)
            fsm_results3 = re_table3.ParseText(raw_text_data3)

            template4 = open("show-memory-statistic.textfsm")  # show memory statistic
            re_table4 = textfsm.TextFSM(template4)
            fsm_results4 = re_table4.ParseText(raw_text_data4)

            template5 = open("show-process-cpu.textfsm")  # show process cpu
            re_table5 = textfsm.TextFSM(template5)
            fsm_results5 = re_table5.ParseText(raw_text_data5)

            outfile_name = open(nameFile2 + "-show-version.csv", "w+")  # show version
            outfile = outfile_name

            outfile_name2 = open(nameFile2 + "-show-env.csv", "w+")  # show env
            outfile2 = outfile_name2

            outfile_name3 = open(nameFile2 + "-show-flash.csv", "w+")  # show flash
            outfile3 = outfile_name3

            outfile_name4 = open(nameFile2 + "-show-memory-statistic.csv", "w+")  # show memory statistic
            outfile4 = outfile_name4

            outfile_name5 = open(nameFile2 + "-show-process-cpu.csv", "w+")  # show process cpu
            outfile5 = outfile_name5

            print(re_table.header)  # show version
            for s in re_table.header:
                outfile.write("%s;" % s)
            outfile.write("\n")

            counter = 0
            for row in fsm_results:  # show version
                print(row)
                for s in row:
                    outfile.write("%s;" % s)
                outfile.write("\n")
                counter += 1
            print("Write %d records" % counter)

            print(re_table2.header)  # show env
            for s in re_table2.header:
                outfile2.write("%s;" % s)
            outfile2.write("\n")

            counter = 0
            for row in fsm_results2:  # show env
                print(row)
                for s in row:
                    outfile2.write("%s;" % s)
                outfile2.write("\n")
                counter += 1
            print("Write %d records" % counter)

            print(re_table3.header)  # show flash
            for s in re_table3.header:
                outfile3.write("%s;" % s)
            outfile3.write("\n")

            counter = 0
            for row in fsm_results3:  # show flash
                print(row)
                for s in row:
                    outfile3.write("%s;" % s)
                outfile3.write("\n")
                counter += 1
            print("Write %d records" % counter)

            print(re_table4.header)  # show memory statistics
            for s in re_table4.header:
                outfile4.write("%s;" % s)
            outfile4.write("\n")

            counter = 0
            for row in fsm_results4:  # show memory statistics
                print(row)
                for s in row:
                    outfile4.write("%s;" % s)
                outfile4.write("\n")
                counter += 1
            print("Write %d records" % counter)

            print(re_table5.header)  # show process cpu
            for s in re_table5.header:
                outfile5.write("%s;" % s)
            outfile5.write("\n")

            counter = 0
            for row in fsm_results5:  # show process cpu
                print(row)
                for s in row:
                    outfile5.write("%s;" % s)
                outfile5.write("\n")
                counter += 1
            print("Write %d records" % counter)
        except IOError:
            print("Error: There Have File does not appear to exist.")
            QMessageBox.question(self, 'Warning', "ERROR:Please check you're '.txt' file and TextFSM File.")

    # ------------- Convert Data to Graphic
    def Graph(self, fileName2):
        fig = plt.figure(figsize=(8.8, 5.5), dpi=150)  # ukuran frame gambar (L X P)
        plt.rcParams['text.color'] = 'k'  # warna tulisan
        plt.rcParams.update({'font.size': 6})  # font size
        plt.subplots_adjust(hspace=.4, right=.8, bottom=.2)  # jarak antar gambar (margin)

        # 1 - show flash
        plt.subplot(2, 2, 1)
        try:
            data = np.loadtxt(fileName2 + '-show-flash.csv', dtype=bytes, delimiter=';', usecols=(0, 1))\
                .astype(str, io.StringIO())

            slices = data[1]
            labels = data[0]
            colors = ['lightskyblue', 'lightcoral']
            explode = [0.08, 0.01]
            pie = plt.pie(slices, labels=labels, colors=colors, explode=explode, startangle=90, shadow=True,
                          autopct='%1.1f%%')

            plt.title('Flash Memory\n(Bytes)')
            plt.legend(pie[0], [" ".join(a) for a in zip(labels, slices)], loc='upper right')
            plt.axis('equal')
        except IOError:
            print("Error: There Have File does not appear to exist.")
            QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")

        # 2 - show memory statistic
        plt.subplot(2, 2, 2)
        try:
            data = np.loadtxt(fileName2 + '-show-memory-statistic.csv', dtype=bytes, delimiter=';',
                              usecols=(3, 4)).astype(str, io.StringIO())
            slices = data[1]
            labels = data[0]
            colors = ['lightskyblue', 'lightcoral']
            explode = [0.08, 0.01]
            pie = plt.pie(slices, labels=labels, colors=colors, explode=explode, startangle=90, shadow=True,
                          autopct='%1.1f%%')

            plt.title('Memory Statistic\n(Bytes)')
            plt.legend(pie[0], [" ".join(a) for a in zip(labels, slices)], loc='upper right')
            plt.axis('equal')
        except IOError:
            print("Error: There Have File does not appear to exist.")
            QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")

        # 3 - show cpu utilization

        plt.subplot(2, 2, 3)

        def autolabel(rects):
            for rect in rects:
                height = rect.get_height()
                plt.text(rect.get_x() + rect.get_width() / 2, height - 2, '%1.1f%%' % int(height), ha='center',
                         va='bottom')
        N = 3
        try:
            data = np.loadtxt(fileName2 + '-show-process-cpu.csv', dtype=bytes, delimiter=';',
                              usecols=(0, 1, 2)).astype(str)

            my_xticks = data[0]
            utilization = data[1]
            utilization_int = [int(x) for x in utilization]

            ind = np.arange(N)
            width = 0.5

            rects1 = plt.bar(ind, utilization_int, width, color='lightblue', )

            plt.title("CPU Utilization\n ('%') ")
            plt.xticks(ind, my_xticks)
            plt.xlabel("CPU Utilization")
            plt.ylabel("Percent(%)")

            autolabel(rects1)
        except IOError:
            print("Error: There Have File does not appear to exist.")
            QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")

        # 4 - CPU Environtment
        plt.subplot(2, 2, 4)

        def autolabel(rects):
            for rect in rects:
                height = rect.get_height()
                plt.text(rect.get_x() + rect.get_width() / 2, height - 5, '%d C' % int(height), ha='center',
                         va='bottom')

        N = 3
        try:
            data = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=2).astype(str)
            value = data[1]
            if value == '':
                try:
                    fan = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=0).astype(str)
                    system_temp = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=1).astype(
                        str)
                    power = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=6).astype(str)
                    rps = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=7).astype(str)

                    uptime = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=3).astype(
                        str)
                    pid = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=5).astype(str)
                    sn = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=6).astype(str)

                    uptime_title = uptime[0]
                    uptime_value = uptime[1]

                    pid_title = pid[0]
                    pid_value = pid[1]

                    sn_title = sn[0]
                    sn_value = sn[1]

                    fan_title = fan[0]
                    fan_status = fan[1]

                    system_temp_title = system_temp[0]
                    system_temp_value = system_temp[1]

                    power_tile = power[0]
                    power_value = power[1]

                    rps_tile = rps[0]
                    rps_value = rps[1]

                    text = fan_title + ' : ' + fan_status + '\n' + system_temp_title + ' : ' + system_temp_value + '\n' \
                           + power_tile + ' : ' + power_value + '\n' + rps_tile + ' : ' + rps_value + ' PRESENT' + '\n\n' \
                           + uptime_title + ' : ' + uptime_value + '\n' + pid_title + ' : ' + pid_value + '\n' + sn_title\
                           + ' : ' + sn_value

                    plt.title("Cpu Environment\n ('Celcius') ")
                    plt.xlabel('CPU Environment')
                    plt.ylabel('Celcius')

                    plt.text(.15, 1 / 3, text, style='oblique', bbox={'facecolor': 'white', 'alpha': 0.5, 'pad': 5})

                    # plt.show('')
                    plt.savefig(fileName2 + '.png', bbox_inches='tight')
                except (IOError):
                    print("Error: There Have File does not appear to exist.")
                    QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
                    plt.savefig(fileName2 + '.png', bbox_inches='tight')
            else:

                try:

                    data = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';',
                                      usecols=(2, 4, 5)).astype(str)
                    fan = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=0).astype(str)
                    system_temp = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';', usecols=1).astype(
                        str)
                    system_temp_state = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, delimiter=';',
                                                   usecols=3).astype(str)

                    uptime = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=3).astype(
                        str)
                    pid = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=5).astype(str)
                    sn = np.loadtxt(fileName2 + '-show-version.csv', dtype=bytes, delimiter=';', usecols=6).astype(str)

                    y_height = np.loadtxt(fileName2 + '-show-env.csv', dtype=bytes, skiprows=1, delimiter=';',
                                          usecols=5).astype(int)

                    uptime_title = uptime[0]
                    uptime_value = uptime[1]

                    pid_title = pid[0]
                    pid_value = pid[1]

                    sn_title = sn[0]
                    sn_value = sn[1]

                    fan_title = fan[0]
                    fan_status = fan[1]

                    system_temp_title = system_temp[0]
                    system_temp_value = system_temp[1]

                    system_temp_state_title = system_temp_state[0]
                    system_temp_state_status = system_temp_state[1]

                    my_xticks = data[0]
                    utilization = data[1]
                    utilization_int = [int(x) for x in utilization]

                    ind = np.arange(N)
                    width = 0.5

                    text = fan_title + ': ' + fan_status + '\n' + system_temp_title + ': ' + system_temp_value + \
                           '\n' + system_temp_state_title + ': ' + system_temp_state_status

                    text2 = pid_title + ' : ' + pid_value + '\n' + sn_title + ' : ' + sn_value +\
                            '\n\n' + uptime_title + ' : ' + uptime_value

                    rects1 = plt.bar(ind, utilization_int, width, color='r')

                    plt.title("CPU Environment\n ('Celcius') ")
                    plt.xticks(ind, my_xticks)
                    plt.xlabel('CPU Environment')
                    plt.ylabel('Celcius')
                    plt.text(2.4, y_height / 2, text)
                    plt.text(-1.59, -y_height / 1.77, text2, style='oblique',
                             bbox={'facecolor': 'red', 'alpha': 0.5, 'pad': 5})
                    autolabel(rects1)

                    # plt.show()
                    plt.savefig(fileName2 + '.png', bbox_inches='tight')

                except (IOError, ValueError):
                    print("Error: There Have File does not appear to exist.")
                    QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
                    plt.savefig(fileName2 + '.png', bbox_inches='tight')

        except (IOError):
            print("Error: There Have File does not appear to exist.")
            QMessageBox.question(self, 'Warning', "Error: There Have File does not appear to exist")
            plt.savefig(fileName2 + '.png', bbox_inches='tight')

    # ------------- SSH Connection
    def sshConection(self):
        for list in self.device_list:
            # time.sleep(0.2)
            # Cisco IOS

            if list.device_type == 'cisco_ios':
                try:
                    print("SSH Connection Establishing---111")
                    net_connect = ConnectHandler(device_type=list.device_type, ip=list.ip, username=list.username,
                                                 password=list.password, secret=list.secret)
                    net_connect.enable()
                    print("SSH Connection Established---222")
                    output = net_connect.find_prompt()
                    hostname = output[:-1]
                    result = net_connect.send_command_expect(list.command, delay_factor=50)
                    try:
                        file = open(hostname + "-" + list.command + ".txt", "w", encoding="utf-8")
                        file.write(result)
                        print("Write File Sucess")
                        nameFile = hostname + "-" + list.command
                        nameFile2 = hostname
                        self.TextFSM(nameFile, nameFile2)
                        self.Graph(nameFile2)
                    except EOFError:
                        print("Faild Write Text File")
                        QMessageBox.question(self, 'Warning', "Faild Write Text File")
                    net_connect.disconnect()

                except (EOFError, SSHException):
                    print("\nError: Connection Faild.")
                    QMessageBox.question(self, 'Warning', "Error: Connection Faild.")

            # CISCO_S300 (SF300)

            elif list.device_type == 'cisco_s300':
                try:
                    net_connect = ConnectHandler(device_type=list.device_type, ip=list.ip, username=list.username,
                                                 password=list.password)
                    output = net_connect.find_prompt()
                    hostname = output[:-1]
                    result = net_connect.send_command(list.command, delay_factor=50)
                    file = open(hostname + "-" + list.command + ".txt", "w", encoding="utf-8")
                    file.write(result)
                    nameFile = hostname + "-" + list.command
                    nameFile2 = hostname
                    self.TextFSM(nameFile, nameFile2)
                    self.Graph(nameFile2)
                    net_connect.disconnect()
                except (EOFError, SSHException):
                    print("\nError: Connection Faild.")

##################################
app = QApplication(sys.argv)
QApplication.processEvents()
app.setStyle('cleanlooks')
window = Widget()
window.show()
sys.exit(app.exec_())

0 个答案:

没有答案